【发布时间】:2015-06-08 10:35:05
【问题描述】:
我正在使用gcc 来编译这个:
int a=1;
printf("%d\n",a);
printf("%f\n",a);
printf("%f\n",(float)a);
我明白了:
1
0.000000
1.000000
为什么隐式转换会给出错误的输出?
【问题讨论】:
我正在使用gcc 来编译这个:
int a=1;
printf("%d\n",a);
printf("%f\n",a);
printf("%f\n",(float)a);
我明白了:
1
0.000000
1.000000
为什么隐式转换会给出错误的输出?
【问题讨论】:
没有转换。 printf 不是接受浮点数的函数。它是一个接受任何类型的参数列表的函数。
编译器假定给出了一个浮点数,而您看到的基本上是未定义的行为。
没有机制可以解析您的输入字符串,然后对每个参数应用自定义转换。你应该非常小心你传递给 printf 的内容,因为可以通过这种方式打开漏洞利用。
【讨论】:
因为在您的平台上,double(%f 所期望的)可能大于 int。没有“隐式转换”;它会将int 作为第二个参数传递,printf() 将读取double。
顺便说一句,这是未定义的行为,不要这样做。
【讨论】:
在您的代码中
int a=1;
//something
printf("%f\n",a);
没有隐式转换,而是格式说明符的不当使用,产生undefined behaviour。
相关:C11 标准,第 7.21.6.1 章,fprintf() 函数
如果有任何参数 不是相应转换规范的正确类型,行为是 未定义。
【讨论】:
因为使用错误的格式说明符是未定义的行为。它可以打印任何东西。
实际上,它取决于 ABI 以及它如何传递浮点参数与 int 参数。在许多系统中,浮点值在为此用途保留的寄存器中传递,而 int 值在不同的寄存器中传递。这里似乎就是这种情况。
【讨论】:
第二个printf 没有转换。您通过不匹配转换说明符("%f")和值类型(int)来调用未定义行为。
【讨论】:
通过执行printf("%f\n",a);,您正在调用未定义的行为。
而通过执行printf("%f\n",(float)a);,您可以输入整数a,因此它会按预期将值打印为浮点数。
【讨论】:
printf 以自己的二进制格式获取其参数。 格式字符串实际上是描述如何解释这种二进制数据。如果此 格式字符串 与实际提供的二进制数据不对应,则该行为充其量是未定义的。
【讨论】: