在C语言中,当被调用的函数没有原型时,编译器会执行默认参数提升。
但是C ++怎么样?什么时候会发生默认参数促销?
在C ++ 11标准5.2.2 / 7中:
当给定参数没有参数时,参数为 以这样的方式传递,即接收函数可以获得该值 通过调用va_arg(18.10)来论证。 [注:本段 不适用于传递给函数参数包的参数。 在模板实例化期间扩展函数参数包 (14.5.3),因此每个这样的参数在a时都有相应的参数 实际上调用了函数模板特化。 - 注意] lvalue-to-rvalue(4.1),array-to-pointer(4.2)和 函数到指针(4.3)标准转换是在 论证表达。具有(可能是cv-qualified)类型的参数 std :: nullptr_t转换为void *(4.10)类型。在这之后 转换,如果参数没有算术,枚举, 指针,指向成员的指针或类类型,程序是不正确的。 传递类型的潜在评估参数(第9条) 有一个非平凡的复制构造函数,一个非平凡的移动构造函数, 或者是一个没有相应参数的非平凡的析构函数 有条件地支持实现定义的语义。如果 参数具有受制于的整数或枚举类型 积分促销(4.5),或受其约束的浮点类型 浮点提升(4.6),参数的值是 在通话前转换为提升类型。这些促销活动是 被称为默认参数促销。
此段落仍未指定何时会发生默认参数提升。如果没有明确的逻辑,这一段可能会说得过多。我努力概述逻辑,但失败了。我不熟悉调用va_arg 。
希望你帮帮我。
答案 0 :(得分:1)
默认促销将在调用函数之前发生,在调用上下文中。
如果您真的在询问执行默认促销活动的情况,请参阅摘录中的内容,尽管它很容易被忽略:“当给定参数没有参数时...... “。换句话说,它与C中的情况基本相同,只是在C ++中不存在不指定参数类型的C风格函数声明。因此,唯一一次没有参数指定其类型的参数是函数具有显式省略号时,例如printf
:int printf(char const *format, ...);
。
答案 1 :(得分:1)
从您在问题中引用的段落开始:“在调用之前,参数的值将转换为提升类型”。
当你调用的函数没有原型时,你说C“默认参数提升” - 但是请记住C ++中不存在这种情况 - 你不能调用一个没有看到声明或定义的函数。 / p>
提及“调用va_arg”意味着在调用函数时会应用某些参数提升,然后使用va_arg
函数访问值(请参阅http://linux.die.net/man/3/va_arg)。可以这样想:一个函数调用可能传递值int(3)
,另一个int(7777)
,另一个char(7)
- 被调用函数应该如何知道期望什么?它可能会将该参数的所有值提升为某个最大支持整数类型,例如int
或long
,然后在函数中使用va_arg
时,它将从{{{{}}转换为int
1}}或long
到va_arg
调用指定的任何整数类型。例如,这确实意味着int(7777)
值可能只传递char
,并且值可能会在没有警告的情况下被截断为8位,但这通常比程序崩溃更好,因为传递的数据字节数与消耗的数量不匹配,或者其他一些奇怪的副作用。