我想知道为什么gcc不支持printf
函数中的默认类型转换。例如:
printf("%f",(7/2));
获取未定义的行为,因为它期待一个浮点数,但得到一个整数值。
但是,如果是-- float f=7/2;
这样的赋值,默认情况下它会进行类型转换。
在printf
中不支持默认类型转换的原因是什么?我不是问C规范,而是问这种规范背后的逻辑是什么。最好有人用一些例子来解释。
发布于 2013-12-20 15:10:13
C语言标准没有指定将printf
参数转换为格式字符串中的类型,因为这将要求编译器解释格式字符串,而不是让printf执行。
一些现代编译器确实会检查printf
字符串,如果它与参数不匹配,则会发出警告。但这是最近的事态发展。在开发C的年代,编译器比现在的软件更简单,增加解释printf
格式字符串的要求在当时是一个不受欢迎的负担。
此外,格式字符串不一定在编译时被知道。您可以编写printf(format, a, b, c)
,其中在运行时计算format
。显然,编译器无法生成简单的代码来将a
、b
和c
转换为字符串format
中的类型。当然,这在理论上是可能的;编译器可以在运行时生成大量的代码来处理所有的情况。但是,对于不需要的功能来说,这将是一项工作量过大的工作。
发布于 2013-12-20 14:43:05
C规范规定了许多'gcc‘必须做的事情。在这种情况下,表达式(7/2)是C语言中的整数表达式,并假装它是浮点数,因为它碰巧是带有(可能是错误的)格式字符串的printf函数的参数之一,这将在很大程度上违反规范,令许多资深程序员感到惊讶。
如果您希望将值转换为浮点数,最简单的方法是乘以1 (即使用(1.0 * 7 / 2)
--但不是(1.0 * (7/2))
,因为这将首先执行整数截断--换句话说,它将首先将(7/2)转换为3,然后乘以1.0*3 = 3.0,而不是您期望的3.5。
发布于 2013-12-20 14:39:09
7/2
产生一个int
,并以这样的方式传递给printf()
。
然后,"f"
转换说明符告诉printf()
从堆栈中提取double
,但是它在传入的int
中找到.-数据。
要按照您的预期行事,编译器需要在编译期间解析格式字符串,以生成传递变量参数的正确代码。它不是这样建造的。
而且很可能永远不会。假设在运行时生成的格式字符串.-没有机会生成正确的代码来传递参数。
https://stackoverflow.com/questions/20705918
复制相似问题