未定义的行为或误报 [英] Undefined behavior or false positive

查看:93
本文介绍了未定义的行为或误报的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我(实质上)在野外遇到以下内容:

  x = x = 5; 

它显然是在早期版本的gcc下清理编译的(在gcc 4.5.1下生成一个警告)。据我所知,警告是由-W序列点产生的。所以我的问题是这是否违反了标准中关于在序列点之间操纵变量的标准(即,它是每个规范未定义的行为)还是这是gcc误报(即,它是按照规范定义的行为)?关于顺序点的措辞有点难以遵循。我说的基本上是因为我实际遇到的(在一个更大的表达式中)是

  x [0] [0] = x [0] [0] = 5; 

但我不认为这对警告是重要的(请纠正我,如果这是对点,而不是我所认为的是问题的症结所在)。

解决方案

假设 x 是内置类型的,它将两次赋值给 x ,而不需要插入顺序点,这就是您所需要知道的。这两个任务具有相同的值(5),并且理论上可以优化为单个任务(如果 x 不是不稳定的),这个事实既不是在这里,也不是在那里。

至少,我是这样解释标准中的修改 - 分配一个值,而不管它是否与旧值相同。同样,抛出const并分配给一个const对象,我认为是UB,不管你分配的值是否等于先前的值。否则,如果一个实现想要将字符串文字放入ROM中,以防止出现页面错误,并且通过检查编译器不会发出该代码,我们知道所有内存写入都会有巨大的开销。



更令人兴奋的例子是 x [0] [0] = x [0] [i] = 5; 如果(且仅当) i == 0 时没有插入序列点的同一对象,则定义的行为以 i



我不明白为什么编译器可能在任何情况下都会做出任何意想不到的事情,但我的想象力再次缺乏是无关紧要的:-)



沃克说的是对的。如果您在某些情况下不能使用两条语句,可能会写 x [0] [0] = 5,x [0] [i] = 5 代替。在你给定的情况下,只是抛弃多余的任务。


I've (essentially) come across the following in the wild

x = x = 5;

which apparently compiles cleanly under earlier version of gcc (generates a warning under gcc 4.5.1). As far as I can tell the warning is generated by -Wsequence-point. So my question is does this violate the wording in the standard about manipulating variables in between sequence points (i.e., it is undefined behavior per the spec) or is this a gcc false positive (i.e., it is defined behavior per the spec)? The wording on sequence points is a bit hard to follow.

I said essentially because what I actually came across (in a larger expression) was

x[0][0] = x[0][0] = 5;

but I didn't think that was material to the warning (please correct me if that is to the point and not what I've assumed is the crux of the matter).

解决方案

Assuming x is of built-in type, it assigns to x twice without an intervening sequence point, which is all you need to know. The fact that both assignments are of the same value (5), and could in theory be optimized into a single assignment (if x is not volatile), is neither here nor there.

At least, that's how I interpret "modified" in the standard - assigned a value, regardless of whether it happens to be the same as the old value. Likewise, casting away const and assigning to a const object is, I think, UB regardless of whether the value you assign happens to be equal to the prior value. Otherwise there's be a huge overhead on all memory writes if an implementation wanted to put string literals into ROM, to prevent a page fault in that case, and we know by inspection that compilers don't emit that code.

A even more exciting example would be x[0][0] = x[0][i] = 5;, which assigns to the same object without an intervening sequence point if (and only if) i == 0, so is defined behaviour conditional on the value of i.

I don't see quite why a compiler might do anything unexpected in either case, but again my lack of imagination is irrelevant :-)

What ablenky says is right. If you're in some context where you can't use two statements, maybe write x[0][0] = 5, x[0][i] = 5 instead. In both your given cases, just ditch the redundant assignment.

这篇关于未定义的行为或误报的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆