gpt4 book ai didi

c - 为什么 GCC 包含一个 "empty"XOR

转载 作者:行者123 更新时间:2023-12-05 08:37:00 26 4
gpt4 key购买 nike

我有以下代码:

typedef struct {
int x;
int y;
int z;
int w;
} s32x4;

s32x4
f() {
s32x4 v;
v.x = 0

return v;
}

生成 (gcc -O2):

f:
xor eax, eax
xor edx, edx ; this line is questionable
ret

clang 输出 (clang -O2):

f:                                      # @f
xor eax, eax
ret

问题

  • GCC 在那里插入一个XOR 是有原因的吗?
  • 如果没有充分的理由:我能以某种方式摆脱它吗?

注意事项

最佳答案

您读取了一个部分未初始化的结构对象以将其返回,即当场 ( arguably ) 未定义行为,即使调用者不使用返回值也是如此。

16 字节的结构在 x86-64 System V ABI 的 RDX:RAX 中返回(任何更大的结构都将通过让调用者传递指向返回值对象的指针来返回)。 GCC 正在清零未初始化的部分,clang 正在留下那里的所有垃圾。

GCC 喜欢在任何时候打破依赖关系,因为可能存在将错误依赖关系耦合到某些东西的风险。 (例如 pxor xmm0,xm​​m0 在使用 badly-designed cvtsi2sd xmm0, eax 之前)。 Clang 在将其排除在外时更加“积极”,有时即使这样做的代码大小好处很小,例如使用 mov al, 1 代替 mov eax,1,或者使用 mov al, [rdi] 代替 movzx eax, byte ptr [rdi])


您看到的最简单形式是返回一个未初始化的普通 int
GCC 和 clang code-gen 之间的相同区别:

int foo(){
int x;
return x;
}

( Godbolt )

# clang 11.0.1 -O2
foo:
# leaving EAX unwritten
ret


# GCC 10.2 -O2
foo:
xor eax, eax # return 0
ret

这里 clang “开始”省略了整个指令。当然这是未定义的行为(读取未初始化的对象),因此标准实际上允许任何内容,包括 ud2(保证引发非法指令异常),甚至省略 ret假设此代码路径无法访问,即永远不会调用该函数。或者返回 0xdeadbeef,或调用任何其他函数,如果您有恶意的 DeathStation 9000 C 实现。

关于c - 为什么 GCC 包含一个 "empty"XOR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66980246/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com