Question

In C language, compiler perform default argument promotion when the function called does not have a prototype.

But how about C++? When will default argument promotions happen?

In C++11 standard 5.2.2/7:

When there is no parameter for a given argument, the argument is passed in such a way that the receiving function can obtain the value of the argument by invoking va_arg (18.10). [ Note: This paragraph does not apply to arguments passed to a function parameter pack. Function parameter packs are expanded during template instantiation (14.5.3), thus each such argument has a corresponding parameter when a function template specialization is actually called. —end note ] The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are performed on the argument expression. An argument that has (possibly cv-qualified) type std::nullptr_t is converted to type void* (4.10). After these conversions, if the argument does not have arithmetic, enumeration, pointer, pointer to member, or class type, the program is ill-formed. Passing a potentially-evaluated argument of class type (Clause 9) having a nontrivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics. If the argument has integral or enumeration type that is subject to the integral promotions (4.5), or 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. These promotions are referred to as the default argument promotions.

This paragraph still does not specify when will a default argument promotion happen. This paragraph may talk too much without a clear logic. I strove to outline the logic but failed. I am not familiar with the invoking va_arg.

Hope you help me.

Was it helpful?

Solution

Default promotions will happen before the function is called, in the calling context.

If you're really asking about the circumstances under which default promotions are carried out, that's covered in the excerpt, though it's such a tiny piece that it's easy to miss: "When there is no parameter for a given argument...". In other words, it's essentially identical to the situation in C, with the exception that a C-style function declaration that doesn't specify parameter types simply doesn't exist in C++. Therefore, the only time you can have an argument without a parameter specifying its type is when a function has an explicit ellipsis, such as printf: int printf(char const *format, ...);.

OTHER TIPS

From the very paragraph you quote in your question: "the value of the argument is converted to the promoted type before the call".

You say of C "default argument promotion when the function called does not have a prototype" - but remember that scenario doesn't exist in C++ - you can not call a function for which no declaration or definition has been seen.

The mention of "invoking va_arg" means that some of the argument promotions are applied when calling a function that will then access the values using the va_arg functions (see http://linux.die.net/man/3/va_arg). Think of it like this: one function call might pass the value int(3), another int(7777), yet another char(7) - how should the called function know what to expect? It will probably promote all values for that parameter to some largest-supported-integral type such as an int or long, then when va_arg is used within the function it will convert from int or long to whatever integral type the va_arg call specifies. This does mean, for example, that int(7777) value might be passed where only a char is expected and the value may be truncated to 8 bits without warning, but that's generally better than having the program crash because the number of bytes of data passed didn't match the number consumed, or some other weird side effect.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top