简体   繁体   中英

Invalid operands comparing a struct to null

I'm trying to debug the following error I have in my code:

#define MAX_PATTERNS 10

typedef struct _kv {
    char* key;
    char* val;
} KV;

void compile(char* pattern)
{
    
    KV patterns[MAX_PATTERNS] = {NULL,};

    for (int idx=0; idx < MAX_PATTERNS; idx++) {
        KV item = patterns[idx];
        printf("%d", item == 0);
    }

}

And I get the following error:

test.c:107:27: error: invalid operands to binary expression ('KV' (aka 'struct _kv') and 'int')
   printf("%d", item == 0);
                ~~~~ ^  ~
 error generated.

What am I doing wrong here? I thought that I could use a patterns[idx] == NULL to test when I can exit the loop (since I'm initializing the array to all zero's), but I seem to be wrong on something. Should I instead check patterns[idx].key to see if that's NULL ?

I suppose one (ugly) way to check if the entire struct is zero'd is by doing:

printf ("Null? %s\n", 
(int) (void*) patterns[0].key + (int) (void*) patterns[0].val == 0? "true" : "false");

Well, the error message says it all... you are trying to compare a struct _kv and an int . It makes no sense to compare objects of completely different types to each other so that's illegal.

But even worse... C doesn't allow you to compare structs using == Not even if the structs are of the same type. Example:

    KV item1 = patterns[idx1];
    KV item2 = patterns[idx2];
    if (item1 == item2) puts("e");

will give an error like:

error: invalid operands to binary == (have ‘KV’ {aka ‘struct _kv’} and ‘KV’ {aka ‘struct _kv’})

To compare structs you need to compare the members one by one.

You ask if it's done like:

(int) (void*) patterns[0].key + (int) (void*) patterns[0].val == 0

The answer is NO

Instead do

patterns[0].key == NULL && patterns[0].val == NULL

If your program compares structs several places in the code, it may be a good idea to write a dedicated compare function - like:

int equal_kv(const KV* a, const KV* b)
{
    return a->key == b->key && a->val == b->val;
}

and use it like:

KV item1 = patterns[idx1];
KV item2 = patterns[idx2];
if equal_kv(&item1, &item2) puts("e");

In my humble point of view, I totally agree with kaylum's point. "item" 's data type is a struct and cannot be compared directly with a integer type variable or literal integer. Instead, in C++, we can use operator overloading to redefine the "==" operator for custom data types such as any custom class or struct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM