我在使用RL78(v. 1.40.6)的IAR编译器时遇到了“未定义行为”警告,代码如下:
static volatile int x[2] = {1, 2};
int test(){
return x[0]+x[1];
}
警告[Pa082]:未定义行为:在该语句C:\sandbox\test. c 32中未定义易失性访问的顺序
编译器tech note提供了一个解释,归结为两个副作用(volatile访问)是无序的。
然而,我可以看到上面的代码对于像GCC 8这样的新编译器来说没有问题。有人能告诉我标准中的变化吗?
2条答案
按热度按时间x6492ojm1#
在同一条语句中访问两个volatile变量并不违法,但是由于标准没有指定
+
操作符的操作数求值的顺序,因此该语言不保证访问的特定顺序。因此,x[0]
之后是x[1]
和x[1]
之后是x[0]
同样正确,并且编译器可以选择它们中的任何一个。因为这可能不是用户所期望的,所以IAR编译器会发出警告。abithluo2#
是否法律的:访问volatile变量可能会有一些副作用,这是由代码之外的东西引起的。例如,阅读x[i]可能会将x的所有元素都设置为值i。
现在这取决于你先读哪一个,它至少是未指定的,但 * 可能 * 是未定义的行为。最好删除未指定的行为。将x[0]和x[1]赋值给两个int,并返回它们的some,这样你的未指定行为就消失了。
为什么一个编译器没有给予警告:没有人强迫它。