【发布时间】:2016-06-18 18:22:57
【问题描述】:
根据this interesting paper about undefined behavior optimization in c,表达式(x<<n)|(x>>32-n)“在n = 0 时在C 中执行未定义的行为”。 This stackoverflow discussion 确认负整数的行为未定义,并讨论了左移值的其他一些潜在缺陷。
考虑以下代码:
#include <stdio.h>
#include <stdint.h>
uint32_t rotl(uint32_t x, uint32_t n)
{
return (x << n) | (x >> (32 - n));
}
int main()
{
uint32_t y = rotl(10, 0);
printf("%u\n", y);
return 0;
}
使用以下参数编译:-O3 -std=c11 -pedantic -Wall -Wextra
- 在 gcc >5.1.0 中,程序的输出是
10。 - 在 clang >3.7.0 中,输出为
4294967295。
有趣的是,使用 c++ 编译时仍然如此:gcc results、clang results。
因此,我的问题如下:
- 根据标准中的语言,我的理解是,这应该不调用未定义/实现定义的行为,因为这两个参数都是无符号整数,并且没有一个值是负数。它是否正确?如果不是,c11 和 c++11 标准的相关部分是什么?
- 如果前面的陈述为真,根据 c/c++ 标准,哪个编译器产生了正确的输出?直观地说,左移没有数字应该会给你返回值,即 gcc 输出的内容。
- 如果不是上述情况,为什么没有警告指出此代码可能会由于左移溢出而引发未定义行为?
【问题讨论】:
标签: c++ c language-lawyer undefined-behavior