C代码输出说明
我遇到了这段代码:
#include<stdio.h>
void main()
{
int x;
float t;
scanf("%f",&t);
printf("%d\n",t);
x=90;
printf("%f\n",x);
{
x=1;
printf("%f\n",x);
{
x=30;
printf("%f\n",x);
}
printf("%f\n",x);
}
printf("%f\n",x);
}
看了一眼,我认为它是标准中引用的一些未定义的输出:
警告:printf 使用其第一个参数来决定有多少个参数 关注以及他们的类型是什么。它会变得混乱,你会得到 错误的答案,如果没有足够的论据,如果它们是 类型错误。
但输出并没有让我不假思索地离开这个问题。
(给出的输入是 23)。
23
0
23.000000
23.000000
23.000000
23.000000
23.000000
为什么总是23.00000?编译器在这里实际上想做什么?为什么它不打印 x
中存储的值,而是打印 t
的值?它有任何解释吗,因为这个未定义的输出似乎定义了一些东西(双关语)。
编辑:
我在 32 位机器上使用 gcc 编译器。
I came across this code:
#include<stdio.h>
void main()
{
int x;
float t;
scanf("%f",&t);
printf("%d\n",t);
x=90;
printf("%f\n",x);
{
x=1;
printf("%f\n",x);
{
x=30;
printf("%f\n",x);
}
printf("%f\n",x);
}
printf("%f\n",x);
}
Glancing at it I thought of it as some undefined output as quoted in standards:
A warning: printf uses its first argument to decide how many arguments
follow and what their type is. It will get confused, and you will get
wrong answers, if there are not enough arguments of if they are the
wrong type.
But the output didn't let me leave this question without giving it second thought.
(input given is 23).
23
0
23.000000
23.000000
23.000000
23.000000
23.000000
Why always 23.00000? What is the compiler actually trying to do here? Instead of messing around with the value stored at x
, why does it print the value of t
? Does it have any explanation, because there seems something defined about this undefined output (pun intended).
Edit:
I am using gcc compiler on 32 bit machine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
程序行为是未定义的,编译器可以做任何事情。
也就是说,我能够在我的系统上重现此行为,并且浏览一下程序集输出即可了解发生的情况:
printf("%d\n",t);
首先加载浮点值从t
进入 CPU 寄存器%xmm0
,该寄存器在我的平台上用于将浮点参数传递给函数。对 printf() 的调用不会访问该寄存器,因为它正在寻找整数输入。对
printf()
的后续调用都不会将任何值加载到%xmm0
中,因为您没有将任何浮点值传递到 printf 或任何其他函数中。但是,当每个printf
在其格式字符串中遇到%f
时,它会从%xmm0
读取,其中仍然包含23.0
来自 CLang 的汇编输出,使用带有
float t = 23.0;
的更简单程序The program behavior is undefined, the compiler is permitted to do anything at all.
That said, I am able to reproduce this behavior on my system and a glance at the assembly output shows what happens:
printf("%d\n",t);
begins by loading the floating point value fromt
into the CPU register%xmm0
which is used on my platform to pass floating-point arguments to functions. That register is not accessed by this call toprintf()
, since it is looking for an integer input instead.None of the subsequent calls to
printf()
load any values into%xmm0
, since you're not passing any floating-point values into printf or into any other function. But when eachprintf
encounters%f
in its format string, it reads from%xmm0
, which still contains23.0
Assembly output, from CLang, using a simpler program with
float t = 23.0;
如果您确实想知道是什么产生了这里的行为,您需要查看此(完全损坏的)C 代码正在为您的特定编译器和 CPU 翻译成的汇编代码。
If you really want to know what is producing the behavior here, you need to look at the assembly code this (completely broken) C code is being translated to for your particular compiler and CPU.