1

GCC在 Linux 上使用编译器。
我想使用 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定义,我的意思是在代码中?

4

2 回答 2

4

在 64 位模式下,gcc 使用 LP64 约定。这意味着long和指针是 64 位宽,但int仍然只有 32 位宽。在表达式中

  int test =(((0) & 0x00000000) << (32));

常量都假定为ints,因为int它大到足以容纳所有常量,并且ints 始终只有 32 位。类型的 shift >= width 的结果是 C 中的 UB,因为行为通常取决于底层架构的 shift 指令。

通过强制其中一个数字为 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
于 2013-10-15T10:46:59.260 回答
2

在 C 中,左移操作数的类型是int,在所讨论的两个平台上都是 32 位的,因此就 C 语言而言,移位始终是未定义的行为。

我想在您的汇编程序中,操作数分别是 32 位或 64 位。

于 2013-10-15T10:33:57.653 回答