简体   繁体   English

为什么GCC在这个例子中没有发出警告

[英]Why doesn't GCC throw a warning in this example

With -Wsequence-point enabled, GCC should warn user when undefined behavior code is spotted. 启用-Wsequence-point ,GCC应在发现未定义的行为代码时警告用户。 For example 例如

b = a + ++a;

should be noticed by GCC and should be reported as "undefined behavior" code (because ISO C doesn't specify the order of evaluating operands for addition). 应该被GCC注意到并且应该被报告为“未定义的行为”代码(因为ISO C没有指定评估操作数的顺序)。

However, I played with the syntax and I tried this one: 但是,我玩了语法,我尝试了这个:

int *a = malloc(sizeof(int) * 2);
a[0] = 1;
printf("%d\n", *(a + (*a)++ - *a));

Of course, I got the warning 当然,我收到了警告

warning: operation on '*a' may be undefined [-Wsequence-point] 警告:'* a'上的操作可能未定义[-Wsequence-point]

which is what I expected, because the value of *a (which is a[0] ) may be incremented or may not be while processing the third operand. 这是我所期望的,因为*a (其为a[0] )的值可以在处理第三个操作数时递增或者可以不递增。 But, I tried the following one: 但是,我尝试了以下一个:

int *a = malloc(sizeof(int) * 2);
a[0] = 1;
printf("%d\n", *(a + (*a)++ - 1));

I was surprised because I got no warnings. 我很惊讶,因为我没有收到任何警告。 Shouldn't this be UB too? 这不应该是UB吗? I mean, according to ISO C99, post increment operation may be evaluated at any point durring expression evaluation (except for comma operators and ternary operators). 我的意思是,根据ISO C99,可以在表达式评估期间的任何点评估后增量操作(逗号运算符和三元运算符除外)。 In my latter example, I am not incrementing pointer, but instead the integer it points to. 在我的后一个例子中,我没有递增指针,而是指向它指向的整数。 So, accordning to the standard, it can be incremented at any point (which means that it can be incremented after whole expression is evaluated), so the program may print both 1 or 2 , right? 因此,根据标准,它可以在任何点递增(这意味着它可以在评估整个表达式后递增),因此程序可以打印12 ,对吧?

Why doesn't GCC throw any warnings? 为什么海湾合作委员会没有发出任何警告? Or did I miss something? 还是我错过了什么? Did I wrongly understand the specs? 我错误地理解了这些规格吗?

Static analysis tool of gcc does not handle this situation. gcc的静态分析工具不能处理这种情况。

The expression *(a + (*a)++ - x) is too hard for static analysis of gcc, because it results in undefined behavior due to lack of sequence point under some very specific circumstances - namely, when *a contains x . 表达式*(a + (*a)++ - x)对于gcc的静态分析来说太难了,因为在某些非常特殊的情况下由于缺少序列点而导致未定义的行为 - 即,当*a包含x This is when (*a)++ - x "undo" each other, so overall expression becomes equivalent to *a plus some side effects. 这是当(*a)++ - x “撤消”彼此时,所以整体表达式相当于*a加上一些副作用。

In order for gcc code analysis to spot this error, the compiler must track the content of *a throughout its lifetime. 为了使gcc代码分析能够发现此错误,编译器必须在整个生命周期内跟踪*a的内容。 Although it looks simple in your example, a more complex program, say, where data is read into a from user input, renders such analysis impossible. 虽然看起来在你的榜样简单,更复杂的程序,也就是说,在数据读入a来自用户的输入,使得这样的分析是不可能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM