[ACCEPTED]-Default argument promotions in C function calls-promotions

Accepted answer
Score: 41

Upvoted AProgrammer's answer—those 17 are the real goods.

For those of you who 16 are wondering why things are this way: in the 15 dark ages before 1988, there was no such 14 thing as a function prototype in classic 13 "K&R" C, and the default argument promotions 12 were instituted because (a) there were 11 essentially "free", as it costs no more 10 to put a byte in a register than to put 9 a word in a register, and (b) to cut 8 down on potential errors in parameter passing. That 7 second reason never quite cut it, which 6 was why the introduction of function prototypes 5 in ANSI C was the single most important 4 change ever in the C language.

As to when 3 default promotions kick in: default argument promotions are used exactly when the expected type of the argument is unknown, which is to 2 say when there's no prototype or when the 1 argument is variadic.

Score: 37
  • (Non variadic) parameters to functions with 25 a prototype are converted to the corresponding 24 type, which can be char, short, float.

  • Parameters 23 to functions without prototype and variadic 22 parameters are subject to default argument 21 promotions.

If you define a function with 20 a prototype and use it without the prototype 19 or vise versa and it has parameters of type 18 char, short or float, you'll probably have 17 a problem at run-time. You'll have the 16 same kind of problems with variadic functions 15 if the promoted type doesn't match what 14 is used when reading the argument list.

Example 13 1: problem when defining a function with 12 a prototype and using it without.

definition.c

void f(char c)
{
   printf("%c", c);
}

use.c

void f();

int main()
{
   f('x');
}

can 11 fail because an int will be passed and the 10 function expect a char.

Example 2: problem 9 when defining a function without a prototype 8 and using it with one.

definition.c

void f(c)
   char c;
{
   printf("%c", c);
}

(This 7 is kind of definition is very old fashioned)

use.c

void f(char c);

int main()
{
   f('x');
}

can 6 fail because an int is expected but a char 5 will be passed.

Note: you'll remark that 4 all functions from the standard library 3 have types which result from default promotions. So 2 they didn't cause problem during the transition 1 when prototypes were added.

Score: 17

Your confusion stems from a very slight 11 misunderstanding of the terminology - both 10 declarations and definitions can include 9 prototypes (or not):

void func(int a, char b, float c);

That is a function declaration that 8 includes a prototype.

void func(int a, char b, float c) { /* ... */ }

That is a function 7 definition that includes a prototype.

"Prototyped" and 6 "non-prototyped" are just attributes of 5 a function type, and both declarations and definitions 4 introduce the type of the function.

So you 3 can have a declaration without a prototype:

void func();

or 2 you can have a definition without a prototype 1 (K&R C style):

void func(a, b, c)
    int a;
    char b;
    float c;
{ /* ... */ }

More Related questions