Is this code undefined behavior?
extern long f(long x);
long g(int x)
{
return f(x);
}
According to the C11 standard, in 6.5.2.2 §6:
If the function is defined with a type that includes a prototype, and [...] the types of the arguments after promotion are not compatible with the types of the parameters, the behavior is undefined.
In the example above, the function f
is defined with a type that includes a prototype and the type of the argument x
is int
while the type of the parameter x
is long
. According to 6.2.7 §1:
Two types have compatible type if their types are the same.
Therefore, long
and int
are not compatible, so the behavior is undefined, right?
However, in 6.5.2.2 §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.
If I correctly understand this paragraph, it means the argument x
which is of type int
is implicitly converted to long
when the function is called. According to 6.3.1.3 §1:
When a value with integer type is converted to another integer type other than
_Bool
, if the value can be represented by the new type, it is unchanged.
As int
has a lower rank than long
, every int
variable can be represented by a long
variable. Therefore, the argument x
can be converted into a long
. Therefore, this is not undefined behavior.
Which interpretation of the standard is right? Is my code undefined behavior or not?