Difficulty: Medium
Correct Answer: Because printf is a variadic function that uses an ellipsis, the C standard does not require compile time checking of additional argument types against the format string, so mismatches can pass without mandatory warnings.
Explanation:
Introduction / Context:
Type safety with printf style functions is a classic point of discussion in C. The format string describes the types of arguments that follow, but the compiler is not always obliged to check that the actual argument types match the format specifiers. This question focuses on why a mismatch between "%d" and a long int argument may not produce a diagnostic in strictly conforming C code, even though it leads to undefined behaviour at run time.
Given Data / Assumptions:
Concept / Approach:
In C, functions with a variable number of arguments are declared with an ellipsis in their parameter list. For such functions, only the arguments that match fixed parameters in the prototype are subject to normal type checking and default promotions. The additional arguments passed through the ellipsis are not fully checked by the standard rules, because the compiler does not know their types. Instead, it is the responsibility of the programmer to ensure that the types of the arguments and the format specifiers agree. Some compilers add extra warnings as a helpful extension, but these are not mandated by the standard.
Step-by-Step Solution:
Step 1: Recall the declaration of printf: int printf(const char *format, ...); where ... denotes a variable number of additional arguments.
Step 2: Understand that only the first parameter, the format string, has a fully specified type in the prototype.
Step 3: Realise that the compiler cannot, by default, know the types of the arguments after the ellipsis based solely on the format string.
Step 4: Recognise that the C standard does not require the compiler to parse the format string to check consistency with the variadic arguments.
Step 5: Conclude that code like printf("%d", (long)num); violates the calling convention and leads to undefined behaviour, but a diagnostic is not strictly required.
Verification / Alternative check:
Checking compiler documentation shows that many compilers provide optional warnings such as -Wall or -Wformat to detect mismatches between format strings and argument types. These are described as diagnostics based on extension rules, not as requirements of the core C standard. When these options are disabled, the same code may compile silently, illustrating that language rules do not mandate format checking.
Why Other Options Are Wrong:
Option B incorrectly claims that long int and int always have the same size, which is not guaranteed; C only specifies minimum ranges. Option C suggests that the compiler rewrites format strings automatically, which is not a feature of standard C. Option D misdescribes printf as a macro that ignores the format string at compile time; in fact, printf is usually a real function, and even if a macro is used, that does not explain the absence of mandated type checking.
Common Pitfalls:
Programmers sometimes assume that the compiler will always protect them from such mismatches, leading to subtle bugs when format specifiers and argument types diverge. Another pitfall is to rely on the absence of warnings as proof of correctness. In C, especially with variadic functions, you must treat the format string as a contract and ensure manually that every specifier matches the type and promotion of its corresponding argument.
Final Answer:
The compiler is not required to warn because printf is variadic and the C standard does not mandate compile time checking of argument types after the ellipsis against the format string, so a long int passed to "%d" can slip through without a diagnostic.
Discussion & Comments