我有一个简单而愚蠢的代码片段需要分析。 从本质上讲,它执行的操作如下:
a = b = c;
但这些类型非常棘手 我在一个地方:
int a,c;
unsigned int b;
在另一个地方我有:
int a;
unsigned int b,c;
如果编译器解释a = b,那么我将unsigned int转换为int
好的,对于2补码,无论如何,这种转换都是无操作的
但是这种转换可能会溢出,这将是UB,是不是?
在这种情况下,编译器有许可证假设我不依赖于UB,因此最终可以考虑&gt; = 0无条件并消除进一步的测试if(a<0) blah...
它是否仍然正确?
在这种情况下,两段代码都会产生相同的行为。
如果编译器解释a = c
并且我认为这是做什么的,并且如果我的上述UB分析是正确的,那么这两段代码可以给出不同的结果。
那么这些表达式如何被解释a=b
或a=c
,或者换句话说,在哪种情况下可以消除这样的(a<0)
分支,只有一个,两者都没有?
最后请注意,我的确切情况是内联函数中的返回值,但我认为它不会改变上面的结论,对吧?
static inline int a1(unsigned int *b,unsigned int c) {return *b=c;}
static inline int a2(unsigned int *b,int c) {return *b=c;}
答案 0 :(得分:1)
a = b = c;
与
相同a = (b = c);
在您的两个示例中有效。
但是这样的演员会溢出,这将是UB,是不是?
没有强制转换,而是从一种类型到另一种类型的隐式转换。
将类型unsigned int
的值转换为int
时,如果unsigned int
中的int
值无法表示,则转换结果可以是实现定义的,也可以是实现 - 引发了定义的行为信号。严格来说,这仍然不是溢出,这不是未定义的行为。