我有一个简单而愚蠢的代码片段要分析。本质上,它执行以下操作:
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=b
or 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;}