我在Linux上使用GCC
编译器
我想使用64位编译器并使用-m32
选项(32位兼容性)构建我的一些文件。我发现编译器的行为很奇怪(对我而言)
我的代码很简单:
int main () {
int test =(((0) & 0x00000000) << (32));
return 0;
}
对于此代码,我收到了32
,64
和64
与-m32
编译器的警告:
warning: left shift count >= width of type [enabled by default]
但是当我试图从assebmly code
编译它时:
.quad (((0) & (0x00000000)) << (32))
我只收到了32 bit
编译器的警告:
Warning: shift count out of range (32 is not between 0 and 31)
为什么不同编译器(32位和64位)从c
和asm
文件编译的相同代码的警告不同?
编辑:
我在哪里可以找到.quad
定义,我的意思是代码?
答案 0 :(得分:4)
在64位模式下,gcc使用LP64约定。这意味着long
和指针是64位宽,但int
仍然只有32位宽。在表达式
int test =(((0) & 0x00000000) << (32));
这些常量都假定为ints
,因为int
足以容纳所有常量,int
s总是只有32位。移位&gt; =类型宽度的结果是C中的UB,因为行为通常取决于底层架构的移位指令。
通过强制其中一个数字为64位来抑制警告。
long test =(((0) & 0x00000000L) << (32)); // Still gives a warning with -m32
或
long long test =(((0) & 0x00000000LL) << (32)); // No warning, long long is always 64 bit
答案 1 :(得分:2)
在C中,移位的左操作数的类型是int
,在所讨论的两个平台上都是32位,因此根据C语言,移位始终是未定义的行为。
我想在你的汇编程序中,操作数分别是32位或64位。