我正在做一个个人项目,我做了这种代码(在一个静态的小辅助函数中):
char *tmp = NULL;
if ((tmp = strchr(mode, 'b') != NULL) && tmp - mode < 3) return BINARY_MODE;
else // ...
然后当我尝试使用 GCC 12 (Ubuntu 12.2.0-3ubuntu1) 进行编译时,我收到了这个警告:
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;
| ^
我尝试解决问题的唯一方法(至少抑制了警告)是在条件之前分配 strchr 的返回值。 这是一个错误还是我只是错过了什么?在这两种情况下,生成的程序都按我预期的方式工作。
在这个子表达式中:
(tmp = strchr(mode, 'b') != NULL)
不等式运算符
!=
的优先级高于赋值运算符=
。所以上面等价于:
(tmp = (strchr(mode, 'b') != NULL))
这意味着您正在分配比较的结果,其类型为
int
并产生值0或1,并将其分配给char *
,这就是您收到警告的原因。
需要先加括号才能进行赋值:
((tmp = strchr(mode, 'b')) != NULL)
编译器看到:
if ((tmp = strchr(mode, 'b') != NULL) && tmp - mode < 3) return BINARY_MODE;
你声称你有:
if ((tmp = strchr(mode, 'b')) != NULL && tmp - mode < 3) return BINARY_MODE;
注意在
)
和'b'
之后的右括号NULL
数量上的差异。你声称你得到的是正确的代码——现在你需要确保这是编译器看到的。
编译器仍然看到错误的代码,但你现在承认你给了它错误的代码。
那段代码相当于写:
if ((tmp = (strchr(mode, 'b') != NULL)) && tmp - mode < 3) return BINARY_MODE;
将比较结果分配给
tmp
——将 int
分配给 char *
,因为编译器在错误消息中抱怨。
正确的密码是您最初声称拥有的密码。您需要确保赋值与 null 进行比较,而不是调用
strchr()
. 的结果
所以,解决方法是写:
if ((tmp = strchr(mode, 'b')) != NULL && tmp - mode < 3) return BINARY_MODE;
代码“似乎”起作用了,因为您将
0
或 1
分配给了 tmp
,然后从中减去 mode
指针得到一个负的 ptrdiff_t
值,这是负的。我想你一定是在 b
存在的情况下进行了测试,而不是在 b
不存在的情况下进行了测试。