C: type conversion when passing an argument on a function call

Casts are irrelevant, it’s the (possibly implicit) prototype that matters.

void foo(short s) {
    // do something
}

int main(void) {
  signed char c="a";

  foo(c);  // c is promoted to short by explicit prototype
  bar(c);  // c is promoted to int by implicit prototype
}

void bar(int i) {
    // do something
}

When the book says “an argument of a function call is an expression” it means that the same type promotion rules apply. It might be easier to understand if you think of a function argument as an implicit assignment to the variable specified in the function prototype. e.g. in the call to foo() above there’s an implicit short s = c.

This is why casts don’t matter. Consider the following code snippet:

signed char c="a";
int i = (short) c;

Here the value of c is promoted first to short (explicitly) then to int (implicitly). The value of i will always be an int.

As for char and short becoming int and float becoming double that refers to the default types for implicit function prototypes. When the compiler sees a call to a function before it has seen either a prototype or the definition of the function it generates a prototype automatically. It defaults to int for integer values and double for floating-point values.

If the eventual function declaration doesn’t match to implicit prototype, you’ll get warnings.

Leave a Comment