gpt4 book ai didi

c - 为什么 clang 会为我使用 -O1 而不是 -O0 编译的 C 代码产生错误的结果?

转载 作者:太空宇宙 更新时间:2023-11-04 02:28:06 25 4
gpt4 key购买 nike

对于输入 0xffffffff,以下 C 代码无需优化即可正常工作,但在使用 -O1 编译时 会产生错误结果。其他编译选项是 -g -m32 -Wall。该代码在 macOS 10.13.2 中使用 clang-900.0.39.2 进行了测试。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
if (argc < 2) return 1;

char *endp;
int x = (int)strtoll(argv[1], &endp, 0);

int mask1 = 0x55555555;
int mask2 = 0x33333333;
int count = (x & mask1) + ((x >> 1) & mask1);

int v1 = count >> 2;
printf("v1 = %#010x\n", v1);

int v2 = v1 & mask2;
printf("v2 = %#010x\n", v2);

return 0;
}

输入:0xffffffff

带 -O0 的输出:(预期)

v1 = 0xeaaaaaaa

v2 = 0x22222222

带 -O1 的输出:(错误)

v1 = 0x2aaaaaaa

v2 = 0x02222222

下面是“int v1 = count >> 2;”这一行的反汇编指令与 -O0 和 -O1。

使用-O0:

sarl $0x2, %esi

使用-O1:

shrl $0x2, %esi

下面是“int v2 = v1 & mask2;”这一行的反汇编指令与 -O0 和 -O1。

使用-O0:

andl -0x24(%ebp), %esi //-0x24(%ebp) stores 0x33333333

使用-O1:

andl $0x13333333, %esi //why does the optimization changes 0x33333333 to 0x13333333?

此外,如果 x 在本地设置为 0xffffffff 而不是从参数中获取其值,即使使用 -O1,代码也将按预期工作。

P.S:该代码是基于我在 CMU 的 CS:APP 类(class)中对 Data Lab 的解决方案的实验性代码。实验要求学生实现一个函数,该函数计算一个 int 变量的 1 位的数量不使用除 int 以外的任何类型

最佳答案

正如一些评论者所指出的,右移有符号值定义不明确

我把x的声明和初始化改成了

unsigned int x = (unsigned int)strtoll(argv[1], &endp, 0);

并在-O0 和-O1 下得到了一致的结果。 (但在进行更改之前,我能够在 MacOS 下通过 clang 重现您的结果。)

关于c - 为什么 clang 会为我使用 -O1 而不是 -O0 编译的 C 代码产生错误的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47934277/

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