I have a few questions about the default argument promotions when calling a function in C. Here's section 6.5.2.2 "Function calls" Paragraphs 6, 7, and 8 from the C99 standard (pdf) (emphasis added and broken into lists for ease of reading):
Paragraph 6
- If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type
float
are promoted todouble
. These are called the default argument promotions.- If the number of arguments does not equal the number of parameters, the behavior is undefined.
- If the function is defined with a type that includes a prototype, and either the prototype ends with an ellipsis (
, ...
) or the types of the arguments after promotion are not compatible with the types of the parameters, the behavior is undefined.- If the function is defined with a type that does not include a prototype, and the types of the arguments after promotion are not compatible with those of the parameters after promotion, the behavior is undefined, except for the following cases:
- one promoted type is a signed integer type, the other promoted type is the corresponding unsigned integer type, and the value is representable in both types;
- both types are pointers to qualified or unqualified versions of a character type or
void
.
Paragraph 7
- If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type.
- The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.
Paragraph 8
- No other conversions are performed implicitly; in particular, the number and types of arguments are not compared with those of the parameters in a function definition that does not include a function prototype declarator.
char
and short
to int
/unsigned int
and float
to double
printf
) are subject to the default argument promotionsFor the record, my understanding of a function prototype is this:
void func(int a, char b, float c); // Function prototype void func(int a, char b, float c) { /* ... */ } // Function definition
I'm having a really hard time groking all of this. Here are some questions I have:
Another important feature of method calls is argument promotion—implicitly converting an argument's value to the type that the method expects to receive (if possible) in its corresponding parameter.
A default argument is a value provided in a function declaration that is automatically assigned by the compiler if the calling function doesn't provide a value for the argument.
Upvoted AProgrammer's answer—those are the real goods.
For those of you who are wondering why things are this way: in the dark ages before 1988, there was no such thing as a function prototype in classic "K&R" C, and the default argument promotions were instituted because (a) there were essentially "free", as it costs no more to put a byte in a register than to put a word in a register, and (b) to cut down on potential errors in parameter passing. That second reason never quite cut it, which was why the introduction of function prototypes in ANSI C was the single most important change ever in the C language.
As to when default promotions kick in: default argument promotions are used exactly when the expected type of the argument is unknown, which is to say when there's no prototype or when the argument is variadic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With