GCC unexpected warning?

I was working on a personal project and I made this kind of code (in a static little helper function) :

char *tmp = NULL;
if ((tmp = strchr(mode, 'b') != NULL) && tmp - mode < 3) return BINARY_MODE;
else // ...

Then when I tried to compile with GCC 12 (Ubuntu 12.2.0-3ubuntu1), I had this warning :

warning: assignment to ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
   31 |     if ((tmp = strchr(mode, 'b') != NULL) && tmp - mode < 3) return BINARY_MODE;
      |              ^

The only thing I tried that solved the problem (at least that suppressed the warning) was to assign the return value of strchr before the conditional.
Is this a bug or did I just miss something ? In both cases the resulting program was working as I expected though.

>Solution :

In this subexpression:

(tmp = strchr(mode, 'b') != NULL)

The inequality operator != has higher precedence than the assignment operator =. So the above is equivalent to:

(tmp = (strchr(mode, 'b') != NULL))

Which means you’re assigning the result of a comparison, which has type int and results in the values 0 or 1, and assigning that to a char *, which is why you’re getting the warning.

You need to add parenthesis to perform the assignment first:

((tmp = strchr(mode, 'b')) != NULL)

Leave a Reply