I'm reading N1256 6.5.2.2 function call. Some parts were hard to understand to me. I googled with bold sentences or some keywords but couldn't find a straightforward answer to my question. So I ask mine.
At 6.5.2.2 p5(emphasize mine)
If the expression that denotes the called function has a type pointer to function returning an object type, the function call expression has the same type as that object type and has the value determined as specified in 6.8.6.4. Otherwise, the function call has type void. If an attempt is made to modify the result of a function call or to access it after the next sequence point, the behavior is undefined.
Q1. What's the meaning of the bold sentence? Is there a way to modify the result of a function call or access it after the next sequence point?
A part of 6.5.2.2 p6(emphasize mine)
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 to double. 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: ...
At 6.7 p4, for the definition of compatible types.
All declarations in the same scope that refer to the same object or function shall specify compatible types.
Formal parameters are not an object, just a placeholder. Q2. Can arguments of a function call and a parameter be the same object? Q3. And why does the standard compare a promoted argument with a parameter? If there is a parameter to compare, promotion won't happen because default argument promotion happens only if the compiler doesn't know what data type callee expects.
(Replacing previous answer)
For Q3, this seems to be about the case where the expression denoting the called function does not include a prototype, but the function definition does. In that case the arguments will be subject to promotion.
void foo1(short s) { // defined with a prototype
// ...
}
void foo2(int i) { // defined with a prototype
// ...
}
void bar(void) {
void (*ptr)(); // no prototype
char c = 'x';
short s = 8;
int i = 1234;
long l = 12345678;
ptr = foo1;
ptr(c); // UB; char promoted to int which is not compatible with short
ptr(s); // Also UB! short promoted to int which is not compatible with short
ptr(i); // likewise UB
// AFAICT there is no way to call foo1 through ptr without UB
ptr = foo2;
ptr(c); // OK; char promoted to int which is compatible with int
ptr(s); // likewise OK
ptr(i); // likewise OK
ptr(l); // UB; long is not compatible with int.
}