What is the purpose of defined() operator in preprocessor conditionals?
ATo check if a macro is defined
BTo define a new macro conditionally
CTo undefine a macro
DTo check if a variable is initialized
Correct Answer:
A. To check if a macro is defined
EXPLANATION
defined(MACRO) is used in #if and #elif directives to test if a macro is defined. Example: #if defined(DEBUG) ... #endif. It's equivalent to #ifdef but can be used in expressions with logical operators like && and ||.
Which of the following will cause infinite recursion when used?
#define RECURSE() RECURSE()
AIt will cause stack overflow at runtime
BThe preprocessor detects recursion and stops expansion
CIt will expand infinitely, causing preprocessor to hang
DIt will cause compilation error
Correct Answer:
C. It will expand infinitely, causing preprocessor to hang
EXPLANATION
The C preprocessor does not detect or prevent recursive macro expansion in its definition. RECURSE() will expand to RECURSE() infinitely, causing the preprocessor to hang or run out of memory. Modern compilers have safeguards, but theoretically this creates infinite expansion.
What happens when #if 0...#endif wraps a block of code?
AThe code is compiled but not executed
BThe code is completely ignored by the preprocessor and not compiled
CIt causes a compilation error
DThe code is commented out
Correct Answer:
B. The code is completely ignored by the preprocessor and not compiled
EXPLANATION
#if 0...#endif is used to disable code during preprocessing. The enclosed code is skipped entirely and doesn't appear in the compiled output. This is more efficient than C-style comments for large blocks and maintains nested comment compatibility.
Which statement about __VA_ARGS__ in variadic macros is CORRECT?
AIt represents all arguments passed to the macro
BIt requires at least one argument to be passed
CIt works in C89/C90 standard
DIt can be used without the three dots (...) in macro definition
Correct Answer:
A. It represents all arguments passed to the macro
EXPLANATION
__VA_ARGS__ (C99 feature) represents all variable arguments after the required parameters. It can be empty if no extra arguments are provided. It must be used with '...' in the macro definition. C89/C90 don't support variadic macros.
Consider nested macro expansion:
#define A B
#define B 5
printf("%d", A);
What is printed?
AB
B5
CCompilation error
DUndefined behavior
Correct Answer:
B. 5
EXPLANATION
The preprocessor expands A to B in the first pass. In the second pass, it recognizes B as a macro and expands it to 5. Nested macro expansion is allowed and the final result is 5. The preprocessor performs multiple expansion passes as needed.
What is the difference between #include and #include "file.h"?
ABoth search in the same directories
B searches system paths first; "" searches current directory first
C"" is only for local files, for system files
DThere is no functional difference; both are equivalent
Correct Answer:
B. searches system paths first; "" searches current directory first
EXPLANATION
#include <file.h> searches in standard system include directories. #include "file.h" searches in the current working directory first, then system directories. This allows you to override system headers with local versions.
Which preprocessor directive is used to generate a compiler warning or error message at compile time?
A#warn and #error
B#error and #pragma message
C#error only
D#warning is the standard directive
Correct Answer:
B. #error and #pragma message
EXPLANATION
#error is standard C and generates a compilation error. #pragma message is commonly supported for warnings. #warn and #warning are non-standard. These are useful for version checking and compile-time notifications.
What will be the output of:
#define MAX(a,b) ((a)>(b)?(a):(b))
int main() { printf("%d", MAX(5++, 10)); return 0; }
A10
B11
CUndefined behavior
D6
Correct Answer:
C. Undefined behavior
EXPLANATION
The macro expands to ((5++)>(10)?(5++):(10)). The variable 5++ is evaluated multiple times due to macro substitution, causing undefined behavior. Increment operations in macro arguments should be avoided. This highlights why inline functions or constexpr functions are preferred in modern C++.
Which of the following correctly uses #pragma once for header file protection in 2024 standards?
A#pragma once is non-standard and should be avoided
B#pragma once is widely supported by modern compilers and is preferred over include guards
C#pragma once and include guards provide identical functionality
D#pragma once can only be used with GCC compiler
Correct Answer:
B. #pragma once is widely supported by modern compilers and is preferred over include guards
EXPLANATION
While #pragma once is technically non-standard, it is supported by virtually all modern compilers (GCC, Clang, MSVC) since 2024. It's simpler than include guards and prevents multiple inclusion more elegantly. Both approaches work, but #pragma once is increasingly preferred.
What does the following preprocessor output?
#define VERSION "2024"
#define STR(x) #x
printf(STR(VERSION));
A2024
BVERSION
C"2024"
D"VERSION"
Correct Answer:
D. "VERSION"
EXPLANATION
Stringification happens before macro expansion of arguments. STR(VERSION) becomes "VERSION" (a string literal of the token VERSION), not the value of VERSION. To stringify the expanded value, use indirect stringification with two levels of macros.