C Quiz: When Is f(n) Actually Called?
emmtrix Tech Posts
Category: C Quiz
Does sizeof evaluate a function call? The answer depends on the type whose size is being determined.
Test your understanding with four expressions involving the same function declaration:
int f(int n);
The question
In which of the following cases is f(n) guaranteed to be called? Select all that apply.
-
A:
(void)f(n) -
B:
sizeof(f(n)) -
C:
sizeof(int[f(n)]) -
D:
sizeof(int (*)[f(n)])
The examples use C with support for variable-length arrays (VLAs). Assume each expression is evaluated separately in a valid program, with positive, valid array bounds.
Take a moment to choose your answers before reading on.
Answer and explanation
The correct answers are A and C.
B does not call the function. In D, whether the array-bound expression is evaluated is unspecified, so the call is not guaranteed.
A: The return value is discarded
(void)f(n)
Casting the result to void discards the return value. The function call is still evaluated.
Result: f(n) is called.
B: Only the return type matters
sizeof(f(n))
The declared return type of f is int. To determine the size of this expression, the compiler needs the size of an int. It does not evaluate the function call.
Result: f(n) is not called.
C: The array size depends on the function result
sizeof(int[f(n)])
Here, int[f(n)] specifies a variable-length array type. Its number of elements depends on the value returned by f(n).
That value is needed to determine the array’s size.
Result: f(n) is called.
D: The pointer size does not depend on the array bound
sizeof(int (*)[f(n)])
This expression asks for the size of a pointer to a variable-length array.
Changing the array bound does not change the size of that pointer. For this case, C leaves it unspecified whether the bound expression is evaluated. Portable code must therefore allow for either outcome. See the C11 draft, sections 6.5.3.4 and 6.7.6.2.
Result: f(n) is not guaranteed to be called.
What to remember
The familiar rule that sizeof does not evaluate its operand has an important exception involving variable-length arrays.
When reviewing C code, pay attention to runtime-dependent array bounds and avoid relying on side effects inside sizeof. The SEI CERT C guidance on unevaluated operands explains the associated pitfalls.
Which expressions are guaranteed to call f(n)? Choose your answers before exploring the explanation below.
Why A and C call f(n), B does not, and D offers no guarantee.