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.
EDIT
Due to the fact that I should have let the initial code I posted (that wasn’t the code I wanted to post), here is the previous one (that was actually good), so everyone can understand the different answers :
char *tmp = NULL;
if ((tmp = strchr(mode, 'b')) != NULL && tmp - mode < 3) return BINARY_MODE;
else // ...
2
Answers
Before the question was hacked
The compiler is seeing:
You are claiming you have:
Notice the difference in the number of close parentheses
)
after the'b'
and afterNULL
. What you claim you’ve got is the correct code — now you need to make sure that’s what the compiler sees.After the question was hacked
The compiler is still seeing the erroneous code, but you now admit that you gave it the erroneous code.
That code is equivalent to writing:
which assigns the result of the comparison to
tmp
— assigning anint
to achar *
as the compiler complains in the error message.The correct code is what you originally claimed to have. You need to ensure that the assignment is compared with null, not the result of calling
strchr()
.So, the fix is to write:
The code ‘appeared’ to work because you assigned either
0
or1
totmp
, and then subtracting themode
pointer from that gives a negativeptrdiff_t
value, and that result is negative, and hence less than 3. I think you probably tested withb
present and not withb
absent.In this subexpression:
The inequality operator
!=
has higher precedence than the assignment operator=
. So the above is equivalent to: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 achar *
, which is why you’re getting the warning.You need to add parenthesis to perform the assignment first: