繁体   English   中英

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

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

启用-Wsequence-point ,GCC应在发现未定义的行为代码时警告用户。 例如

b = a + ++a;

应该被GCC注意到并且应该被报告为“未定义的行为”代码(因为ISO C没有指定评估操作数的顺序)。

但是,我玩了语法,我尝试了这个:

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

当然,我收到了警告

警告:'* a'上的操作可能未定义[-Wsequence-point]

这是我所期望的,因为*a (其为a[0] )的值可以在处理第三个操作数时递增或者可以不递增。 但是,我尝试了以下一个:

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

我很惊讶,因为我没有收到任何警告。 这不应该是UB吗? 我的意思是,根据ISO C99,可以在表达式评估期间的任何点评估后增量操作(逗号运算符和三元运算符除外)。 在我的后一个例子中,我没有递增指针,而是指向它指向的整数。 因此,根据标准,它可以在任何点递增(这意味着它可以在评估整个表达式后递增),因此程序可以打印12 ,对吧?

为什么海湾合作委员会没有发出任何警告? 还是我错过了什么? 我错误地理解了这些规格吗?

gcc的静态分析工具不能处理这种情况。

表达式*(a + (*a)++ - x)对于gcc的静态分析来说太难了,因为在某些非常特殊的情况下由于缺少序列点而导致未定义的行为 - 即,当*a包含x 这是当(*a)++ - x “撤消”彼此时,所以整体表达式相当于*a加上一些副作用。

为了使gcc代码分析能够发现此错误,编译器必须在整个生命周期内跟踪*a的内容。 虽然看起来在你的榜样简单,更复杂的程序,也就是说,在数据读入a来自用户的输入,使得这样的分析是不可能的。

暂无
暂无

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

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