Difficulty: Medium
Correct Answer: The call to va_arg should use double instead of float because floating arguments are promoted to double in variable argument lists
Explanation:
Introduction / Context:
This question checks your understanding of how variable argument lists (varargs) work in C using stdarg.h, especially how default argument promotions apply to floating point values. It also reinforces correct usage of va_arg and how to match the types you retrieve from the variable argument list to the types that were actually passed.
Given Data / Assumptions:
Concept / Approach:
In C, when using variable argument lists, default argument promotions apply to certain types. In particular, float values are promoted to double when passed as variable arguments. This means that although the programmer writes 12.5 in the call, at the ABI level the function actually receives doubles for each of these values. When using va_arg, the type you specify must match the actual type that was passed after promotions. If there is a mismatch, behavior is undefined.
Step-by-Step Solution:
Notice that the call uses floating constants like 12.5 without an explicit suffix.
In C, such constants have type double by default, not float.
When passed through the ellipsis in display, these values are passed as double because of default promotions.
Inside display, the code uses va_arg(ptr, float), which tells va_arg to read only the number of bytes corresponding to a float, not a double, from the argument list.
This mismatch leads to undefined behavior, often manifesting as garbage values or crashes. The correct call is c = (float)va_arg(ptr, double);.
Verification / Alternative check:
You can test this by writing a small program that uses va_arg with float versus double. Using float in va_arg when doubles were passed usually prints nonsense values. When you switch to va_arg(ptr, double) and optionally assign to a float, the output becomes correct, confirming that double is the proper type to use in varargs retrieval for promoted float values.
Why Other Options Are Wrong:
Option a is not the main issue; while having a prototype is good practice, many compilers will still compile this with an implicit int return type warning, but that is not the central conceptual error here.
Option c about the loop index does not reflect any real bug; starting j at 1 and looping to j <= num just matches the count parameter.
Option d is incorrect because printf with "%f" expects a double, not a float. The problem is not the format string but the type passed to va_arg.
Common Pitfalls:
Learners often forget that varargs functions must manually handle default promotions and that float is always promoted to double in this context. Another common mistake is to focus only on the printf format string and ignore the types retrieved by va_arg. Always ensure that the type you give to va_arg matches the actual promoted type of the arguments passed through the ellipsis.
Final Answer:
The primary error is that va_arg must use double, not float, when retrieving the floating arguments from the variable argument list.
Discussion & Comments