这个简单的代码片段是否具有C99标准的完全定义的行为?
{
uint64_t longer = 0x122223333u;
uint32_t shorter = longer;
assert(shorter == 0x22223333u);
}
如果没有,那么符合标准的方法是什么(将uint64_t
值的低32位放到uint32_t
变量中?
答案 0 :(得分:6)
C99标准草案说:
否则,如果新类型是无符号的,则通过重复添加或转换该值 减去一个可以在新类型中表示的最大值 直到该值在新类型的范围内。
因此,在这种情况下,64位值将通过从中重复减去0x1_0000_0000
来转换,直到结果符合32位(为了可读性而添加了下划线)。
在您的情况下,经过一次这样的减法后,结果为0x22223333
。似乎很清楚,可以证明这与截断相同,我真的不认为实际的减法发生了。
答案 1 :(得分:4)
无符号整数类型遵循模块化算法的规则,没有任何未定义的行为,因此赋值完全有效且正确。
除此之外,可选的类型uint32_t
和uint64_t
实际上保证没有填充,并且分别是32或64位宽。
答案 2 :(得分:2)
无符号截断很好地定义为模2^n
。这是签名截断,很棘手,定义较少。
所以是的,这是定义的,断言是真的,无论机器的字节顺序如何。