-3

我有一个简单而愚蠢的代码片段要分析。本质上,它执行以下操作:

a = b = c;

但是类型非常棘手。
在一个地方我有:

int a,c;
unsigned int b;

在另一个地方我有:

int a;
unsigned int b,c;

如果编译器解释 a = b,那么我将 unsigned int 转换为 int
OK,在 2-complement 上,无论如何,这样的转换是空操作
但是这样的转换可能会溢出,这将是 UB,对吗?
在这种情况下,编译器有权假定我不依赖 UB,因此最终可以无条件地考虑 a>=0 并消除进一步的测试if(a<0) blah...,这仍然是正确的吗?

在这种情况下,两段代码都会导致相同的行为。

如果编译器解释a = c并且我认为这就是它所做的,并且如果我上面的 UB 分析是正确的,那么这两段代码可能会给出不同的结果。

那么如何解释这些表达式a=bor 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;}
4

1 回答 1

1
a = b = c;

a = (b = c);

这在你的两个例子中是有效的。

但是这样的演员可以溢出,这将是UB,对吗?

没有强制转换,而是从一种类型到另一种类型的隐式转换。将类型的值转换为unsigned intint,如果该unsigned int值在 中不可表示int,则转换的结果要么是实现定义的,要么是引发实现定义的行为信号。严格来说,这仍然不是溢出,也不是未定义的行为。

于 2013-03-22T22:47:26.770 回答