use*_*769 20 c optimization gcc bit-manipulation shift
在gcc中使用不同的优化级别编译此代码时,我看到了我不期望的行为.
函数测试应使用1填充64位无符号整数,将shift_size位向左移位,并将32位低位作为32位无符号整数返回.
当我用-O0编译时,我得到了我期望的结果.
当我使用-O2编译时,如果我尝试移位32位或更多,我就不会.
实际上,如果我在x86上移位大于或等于位宽的32位整数,那么我得到的结果就是我所期望的结果,这是仅使用移位大小的5个低位的移位.
但我正在转移64位数字,所以转移<64应该是合法的吗?
我认为这是我的理解中的错误而不是编译器中的错误,但我无法弄明白.
我的机器:gcc(Ubuntu/Linaro 4.4.4-14ubuntu5)4.4.5 i686-linux-gnu
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
uint32_t test(unsigned int shift_size) {
uint64_t res = 0;
res = ~res;
res = res << shift_size; //Shift size < uint64_t width so this should work
return res; //Implicit cast to uint32_t
}
int main(int argc, char *argv[])
{
int dst;
sscanf(argv[1], "%d", &dst); //Get arg from outside so optimizer doesn't eat everything
printf("%" PRIu32 "l\n", test(dst));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用法:
$ gcc -Wall -O0 test.c
$ ./a.out 32
0l
$ gcc -Wall -O2 test.c
$ ./a.out 32
4294967295l
Run Code Online (Sandbox Code Playgroud)
"%u"(或"%lu")uint32_t并不一定兼容.尝试
#include <inttypes.h>
//printf("%ul\n", test(dst));
printf("%" PRIu32 "l\n", test(dst));
Run Code Online (Sandbox Code Playgroud)
uint32_t使用"%u"(或"%lu")说明符打印值可以调用未定义的行为.
它看起来像一个错误。我的猜测是编译器已经折叠了最后两行:
res = res << shift_size
return (uint32_t)res;
Run Code Online (Sandbox Code Playgroud)
进入:
return ((uint32_t)res) << shift_size;
Run Code Online (Sandbox Code Playgroud)
后者现在已明确定义为 32 或更大。
| 归档时间: |
|
| 查看次数: |
1130 次 |
| 最近记录: |