use*_*220 29 c gcc gcc-warning
显然,在gcc/C中,编译器编译时
if ((x=0)){ some code }
Run Code Online (Sandbox Code Playgroud)
当使用时
if (x=0){ some code }
Run Code Online (Sandbox Code Playgroud)
使用,然后编译器拒绝编译.
两者有什么不同?
作为一个说明,我知道x==0和之间有什么区别x=0.我正在探索C遇到一些奇怪的代码时的行为方式.
Dav*_*ven 48
代码方面没有区别.
所发生的一切就是说,x=0而不是x==0大多数编译器在看到它时会发出警告(或错误,在你的情况下)这样的常见错误.额外的一组括号是关闭编译器的常用技巧 - 相当于说"是的,我真的打算这样做".
Pav*_*rda 36
两者在语法上都是正确的C,编译器必须处理它.但是,编译器可能会根据配置发出警告甚至错误(例如gcc中的-Werror),因为其中一个是如此可疑,以至于您永远不会想到它是故意的.当你使用类似的东西时if (x = 0) { ... }(x如果零非零则分配零并运行块),你几乎总是实际意味着if (x == 0) { ... }(如果x为零则运行块).
现在让我们了解为什么if ((x = 0)) { ... }不被认为足够可疑以保证相同类型的警告(这个特殊的代码仍然是可疑的,因为条件总是评估为零,并且身体永远不会运行)...
某些C开发人员使用了一个习惯用法(我就是其中之一),你将一个赋值括在括号中并利用这个特性,即使赋值本身也有一个值,它就是赋值.
例:
#include <stdio.h>
int main(int argc, char **argv)
{
int c;
while ((c = getchar()) != '\n')
printf("Character: '%c' (0x%02x)\n", c, c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
测试示例:
$ ./test
Hello!
Character: 'H' (0x48)
Character: 'e' (0x65)
Character: 'l' (0x6c)
Character: 'l' (0x6c)
Character: 'o' (0x6f)
Character: '!' (0x21)
Run Code Online (Sandbox Code Playgroud)
最重要的部分是条件(c = getchar()) != '\n',你第一次分配的结果getchar()来c,然后检查是否有特定的值.在这种情况下,我们从标准输入中逐个读取字符,直到读取一行(技术上直到我们读取一个\n字符).这样做的主要优点是它允许你getchar()填入测试.否则你将不得不使用逗号表示法,带有中断的无限循环,或者在循环之前和循环结束时将它放在一起.
有时候,你比较非零值,比如\n,-1和类似的,但有时你比较为零或者,当指针时,对NULL.让我们找一个例子NULL,这在内存分配中很常见.
char *p;
if ((p = malloc(50)) == NULL) {
...handle error...
}
Run Code Online (Sandbox Code Playgroud)
当然你可以把它写成:
char *p;
p = malloc(50);
if (p == NULL) {
...handle error...
}
Run Code Online (Sandbox Code Playgroud)
但根据您的口味,您还可以使用:
char *p;
if (!(p = malloc(50))) {
...handle error...
}
Run Code Online (Sandbox Code Playgroud)
或者甚至将它转向另一个方向(顺便说一下,我总是首先处理错误情况):
char *p;
if ((p = malloc(50))) {
...do stuff...
} else {
...handle error...
}
Run Code Online (Sandbox Code Playgroud)
在最后一种情况下,条件(p = malloc(50))完全等同于p = malloc(50)但后者是高度可疑的,因为已经提到的在C和派生语言中执行赋值而不是比较的常见错误.请注意,这不仅涉及可疑编译器,还涉及人们阅读代码并查看潜在错误.
冗余括号只是一种告诉读者和编译器的方法,这种分配绝对是有意的,并且不是那种常见错误的发生.
小智 19
除非你有,否则代码不应该"拒绝"编译-Werror.如果您启用了警告,它可能会告诉您:
警告:建议用作真值的赋值括号[-Whatarentheses]
while (*dest++ = *src++)
具体来说,海湾合作委员会的文件说明了这个警告的目的:
如果在某些上下文中省略括号,则会发出警告,例如在预期真值的上下文中存在赋值,或者当嵌套运算符时,优先级通常会让人感到困惑.
| 归档时间: |
|
| 查看次数: |
8384 次 |
| 最近记录: |