Geo*_*etu 1 c c++ debugging coding-style compiler-warnings
在查看某人的代码时,我遇到了类似于下面的情况,其中错误(基本上是一些糟糕的编程习惯)不是直接可见的.根据所使用的编译器,i/i++可能是0或1.
int foo(int n) {
printf("Foo is %d\n", n);
return (0);
}
int bar(int n) {
printf("Bar is %d\n", n);
return (0);
}
int main(int argc, char *argv[]) {
int x = 0;
int(*(my_array[3]))();
int i = 1;
int y = i/++i;
printf("\ni/++i = %d, ", y);
my_array[1] = foo;
my_array[2] = bar;
(my_array[++x])(++x);
}
Run Code Online (Sandbox Code Playgroud)
因此,输出是Foo is 2或者Bar is 2.
我的问题可能被认为过于宽泛,但我想知道:
Foo is 2并且Bar is 2对使用代码的程序员没有任何意义)i/++i导致未定义的行为,就像my_array[++x](++x).
它不是运营商优先级或评估顺序问题; 这是一个排序问题.(编码器可能认为存在与优先级相对应的副作用的顺序,而事实上并非如此).有关更详细的说明,请参阅此主题.
除非您确实知道自己在做什么,否则可以通过不使用递增或赋值运算符作为子表达式来避免这种错误.在这些情况下:
int y = i / (i+1);
++i;
Run Code Online (Sandbox Code Playgroud)
和
my_array[x+1](x+1);
x += 2;
Run Code Online (Sandbox Code Playgroud)
或任何意图.
编译器没有义务检测到这些,尽管有些编译器仍然会这样做.最新版本的gcc应该警告i/++i.如果您认为这还不够好,那么请考虑加入gcc开发团队:)
有静态代码分析工具可以更好地检测未定义的行为.
| 归档时间: |
|
| 查看次数: |
110 次 |
| 最近记录: |