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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…