【问题标题】:When will default argument promotions happen?默认参数提升何时发生?
【发布时间】:2013-06-25 19:48:08
【问题描述】:
在 C 语言中,当调用的函数没有原型时,编译器会执行默认参数提升。
但是 C++ 呢?默认参数提升何时发生?
在 C++11 标准 5.2.2/7 中:
当给定参数没有参数时,参数是
以接收函数可以获取值的方式传递
通过调用 va_arg (18.10) 的参数。 [注:本段
不适用于传递给函数参数包的参数。
在模板实例化期间扩展函数参数包
(14.5.3),因此每个这样的参数都有一个对应的参数,当
实际上调用了函数模板特化。 ——尾注]
左值到右值 (4.1)、数组到指针 (4.2) 和
函数到指针 (4.3) 标准转换是在
论证表达。具有(可能是 cv 限定的)类型的参数
std::nullptr_t 转换为类型 void* (4.10)。在这些之后
转换,如果参数没有算术,枚举,
指针、指向成员的指针或类类型,程序格式错误。
传递类类型的潜在评估参数(第 9 条)
有一个非平凡的复制构造函数,一个非平凡的移动构造函数,
或一个不重要的析构函数,没有相应的参数,是
有条件地支持实现定义的语义。如果
参数具有整数或枚举类型,受
积分促销(4.5),或受制于的浮点类型
浮点提升(4.6),参数的值为
在调用之前转换为提升的类型。这些促销活动是
称为默认参数提升。
本段仍未指定默认参数提升何时发生。这一段可能讲的太多,没有清晰的逻辑。我努力概述逻辑但失败了。我不熟悉调用 va_arg。
希望你能帮助我。
【问题讨论】:
标签:
c++
function-calls
promotions
【解决方案1】:
默认提升将在函数被调用之前发生,在调用上下文中。
如果您真的要询问执行默认促销的情况,摘录中已经介绍了这一点,尽管它是一个很小的部分,很容易错过:“当给定参数没有参数时.. ."。换句话说,它本质上与 C 中的情况相同,只是在 C++ 中根本不存在不指定参数类型的 C 风格函数声明。因此,只有当函数具有显式省略号时,才可以使用不带参数指定类型的参数,例如 printf: int printf(char const *format, ...);。
【解决方案2】:
从您在问题中引用的那一段中:“参数的值在调用之前转换为提升的类型”。
你说 C“当被调用的函数没有原型时默认参数提升”——但请记住,C++ 中不存在这种情况——你不能调用没有看到任何声明或定义的函数。
提到“调用 va_arg”意味着在调用函数时应用了一些参数提升,然后将使用 va_arg 函数访问值(请参阅 http://linux.die.net/man/3/va_arg)。可以这样想:一个函数调用可能传递值int(3),另一个int(7777),还有另一个char(7) - 被调用函数怎么知道会发生什么?它可能会将该参数的所有值提升为某个最大支持的整数类型,例如int 或long,然后当在函数中使用va_arg 时,它将从int 或long 转换为va_arg 调用指定的任何整数类型。这确实意味着,例如,int(7777) 值可能会在只需要 char 的地方传递,并且该值可能会在没有警告的情况下被截断为 8 位,但这通常比程序崩溃要好,因为传递的数据与消耗的数量不匹配,或者其他一些奇怪的副作用。