gpt4 book ai didi

c - 为什么 printf 对于不同的编译器设置 64 和 32 显示错误的 int 变量值?

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

我有以下程序。

int main () {
int a = 1;
long long b = 100000000;
printf("size of a is: %d \t sizeof b is:%d \n",sizeof(a),sizeof(b));
printf("a= %d b=%d a=%d \n", a, b, a);
printf("a= %d b=%Ld a=%d \n", a, b, a);
b = 10000000000;
printf("a= %d b=%d a=%d \n", a, b, a);
printf("a= %d b=%Ld a=%d \n", a, b, a);
}

当我用 gcc -m32 编译它时输出是

size of a is: 4      sizeof b is:8  
a= 1 b=100000000 a=0
a= 1 b=100000000 a=1
a= 1 b=1410065408 a=2
a= 1 b=10000000000 a=1

但是当使用 gcc -m64 编译时输出是。

size of a is: 4      sizeof b is:8  
a= 1 b=100000000 a=1
a= 1 b=100000000 a=1
a= 1 b=1410065408 a=1
a= 1 b=10000000000 a=1

为什么在打印第三个 printf 参数 (a) 时显示错误的值?

我的gcc版本是

priyanka@priyanka-N551JB:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu

最佳答案

您必须使用 %lld 打印 long long 值。您不能使用 %d 打印它们。如果您尝试使用 %d 打印它们,它将不起作用。 (事实证明,%Ld 也不对,尽管听起来 gcc 让您逍遥法外。)

数字 10000000000 需要 34 位来表示。正如您所发现的,它不适合 16 位或 32 位普通 int。但是,它将适合 64 位 long long int

当您尝试使用 %d 打印 64 位 long long 时,很难确切知道会发生什么。您可以想象将 8 个字节压入堆栈,然后 %d 弹出其中的 4 个字节。因此,其他四个仍保留在堆栈中,因此它们是第三个 %d 的弹出值,而不是 a 的实际值。这不一定是实际发生的事情,实际上它可能比这更复杂。复杂性可能很容易取决于您是在 32 位还是 64 位模式下编译。


这最终是对一个重要观点的一个小而简单的说明:当程序使用未定义的行为时,程序的所有方面都可能变得未定义。当你做了一些真正错误的事情时,比如尝试使用 %d 打印 blong long 值,出错的不仅仅是 b 的值打印不正确——其他地方也出错了。

打个比方。假设你买了一辆全新的赛车,轮胎又薄又快。售货员提醒您,这是一辆公路自行车,只能在平坦的柏油路上骑行。销售人员警告说,如果您尝试在越野时驾驶它,如果您撞到石头,轮胎可能会爆裂。

现在,假设您确实骑自行车离开了公路。假设你翻过一 block 岩石,轮胎爆裂,因此你失去控制,撞车, Handlebars 弯曲,前额也被割伤。假设你回到自行车店说,“好吧,我骑自行车离开了公路,轮胎像你说的那样爆了。但是你能解释为什么 Handlebars 弯曲了,我的头上有这个伤口吗?”

关于c - 为什么 printf 对于不同的编译器设置 64 和 32 显示错误的 int 变量值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39928387/

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