C Preprocessor Directives - Tricky MCQ
Tricky Questions on Preprocessor Directives
When does preprocessor execute in compilation process?
Preprocessor runs before actual compilation. It performs text substitution, file inclusion, conditional compilation. Output is expanded source code for compiler. Can be invoked separately (gcc -E). Has no knowledge of C syntax.
What is the difference between #include "file" and #include <file>?
Quotes search current directory then system include paths. Angle brackets search system include paths only. Convention: quotes for project headers, brackets for standard/library headers. Exact search paths compiler-dependent.
What is macro vs function advantage?
Macros are text substitution - no runtime overhead. Generic - work with any type. Can use compile-time constants. Disadvantages: no type checking, multiple evaluation of arguments, harder to debug, code bloat.
What is the problem with #define SQUARE(x) x*x?
Macro arguments should be fully parenthesized. SQUARE(2+3) expands to 2+3*2+3 = 2+6+3 = 11 due to precedence. Correct: ((x)*(x)). Also need parentheses around whole macro if used in expression.
What is token pasting operator (##)?
Token pasting (##) concatenates tokens before evaluation. Useful for creating function/variable names programmatically. Example: #define DECLARE(type, name) type var_##name. Must result in valid token.
What is stringizing operator (#)?
Stringizing (#) converts macro argument to string literal. Example: #define STR(x) #x makes STR(hello) become "hello". Preserves whitespace and quotes. Useful for assertions, debugging, generating strings from code.
What is #pragma directive?
#pragma provides compiler-specific directives. Common pragmas: once (header guards), pack (structure alignment), warning (disable/enable). Behavior varies by compiler. Standardized pragmas in C99: STDC FP_CONTRACT, CX_LIMITED_RANGE.
What is #error directive?
#error stops compilation with custom message. Used to enforce constraints: required macros, platform checks, deprecated features. Similar to static_assert but at preprocessing stage. #warning gives warning without stopping.
What is #undef directive?
#undef removes macro definition. Needed before redefining macro (avoiding warning). Useful for macros local to header file. After #undef, #ifdef MACRO is false. Doesn't affect identical macro defined elsewhere.
What is #line directive?
#line changes line number (and optionally filename) for error reporting. Syntax: #line number "filename". Used by tools generating C code to map errors to original source. __LINE__ and __FILE__ reflect #line values.
What is defined() operator in #if?
defined(MACRO) returns 1 if MACRO defined, 0 otherwise. Used in #if expressions. Allows complex conditions: #if defined(A) && !defined(B). More flexible than #ifdef/#ifndef which only test single macro.
What is #if vs #ifdef difference?
#if evaluates constant integer expression. #ifdef tests if macro defined (regardless of value). #if defined(MACRO) identical to #ifdef MACRO. #if more flexible for complex conditions, version checks.
What is __VA_ARGS__ in variadic macros?
__VA_ARGS__ expands to variable arguments in macro. Syntax: #define LOG(fmt, ...) printf(fmt, __VA_ARGS__). C99 feature. Can be empty if no arguments passed (requires ##__VA_ARGS__ extension for GCC).
What are predefined macros like __LINE__, __FILE__?
Standard predefined macros: __LINE__ (current line), __FILE__ (filename), __DATE__ (compilation date), __TIME__ (compilation time). Compiler-specific: __STDC__, __cplusplus, __GNUC__, _WIN32. Useful for diagnostics, version checks.
What is header guard pattern?
Header guards prevent duplicate definitions when header included multiple times. Traditional: #ifndef UNIQUE_NAME / #define UNIQUE_NAME / #endif. #pragma once is compiler extension (faster, less error-prone). Unique name typically filename_UPPERCASE_H.