为什么 printf() 将浮点数提升为双精度数?
来自之前的问题:p><块引用>
如果您尝试将 float
传递给 printf
,它将被提升为 double
在 printf
收到之前
printf()
是可变参数函数吗?那么可变参数函数是否在传递 float
参数之前将其提升为 double
?
是的,可变参数函数的浮点参数被提升为双精度.
C99 标准草案部分 6.5.2.2
函数调用说:
[...] 和论据具有 float 类型的提升为 double.这些被称为默认参数促销活动.[...]
来自C++ 标准草案 section 5.2.2
函数调用:
[...] 一种受浮点数约束的浮点类型提升(4.6),参数的值转换为在调用之前提升类型.[...]
和4.6
部分:
float 类型的纯右值可以转换为 double 类型的纯右值.值不变
cppreference 涵盖了 默认转换 用于 C++ 中的可变参数函数:
<块引用>- std::nullptr_t 转换为 void*
- float 参数被转换为 double ,就像在浮点提升中一样
- bool、char、short 和无作用域枚举转换为 int 或更宽的整数类型,如整数提升中一样
我们可以在 C 和大概在 C++ 中看到这种转换是为了与 K&RC 兼容而保留的,来自 国际标准的基本原理――编程语言――C(强调我的):
<块引用>为了与过去的做法兼容,所有参数提升都发生在在没有原型声明的情况下在 K&R 中描述,包括将浮点数提升为双倍并不总是理想的.
From a previous question:
If you attempt to pass a
float
toprintf
, it'll be promoted todouble
beforeprintf
receives it
printf()
is a variadic function right? So does a variadic function promote a float
argument to a double
before passing it?
Yes, float arguments to variadic function are promoted to double.
The draft C99 standard section 6.5.2.2
Function calls says:
[...]and arguments that have type float are promoted to double. These are called the default argument promotions.[...]
from the draft C++ standard section 5.2.2
Function call:
[...]a floating point type that is subject to the floating point promotion (4.6), the value of the argument is converted to the promoted type before the call. [...]
and section 4.6
:
A prvalue of type float can be converted to a prvalue of type double. The value is unchanged
cppreference covers the default conversions for variadic function in C++ well:
- std::nullptr_t is converted to void*
- float arguments are converted to double as in floating-point promotion
- bool, char, short, and unscoped enumerations are converted to int or wider integer types as in integer promotion
We can see in C and presumably in C++ this conversion was kept around for compatibility with K&R C, from Rationale for International Standard―Programming Languages―C (emphasis mine):
For compatibility with past practice, all argument promotions occur as described in K&R in the absence of a prototype declaration, including the not always desirable promotion of float to double.
相关文章