5.1.28 · D5 · HinglishC Programming
Question bank — Macros vs inline functions
5.1.28 · D5· Coding › C Programming › Macros vs inline functions
True or false — justify
Har macro invocation compile-check mein ek inline call se zyada slow hoti hai.
False. Macros ko C Preprocessor bilkul type-check nahi karta — ye pure text hain, isliye koi checking hoti hi nahi jo slow ho; danger ye hai ki errors slip through ho jaate hain, na ki checking heavy hoti hai.
inline compiler ko force karta hai ki function body ko call site pe paste kare.
False.
inline ek request/hint hai; optimizer ise ignore kar sakta hai (jaise recursive ya bahut badi functions ke case mein) aur phir bhi ek real call emit karta hai.Ek macro aur ek inline function jo dono "square x" karte hain, hamesha identical machine code produce karte hain.
False. Tabhi jab argument mein koi side effects na hon aur na hi koi precedence surprise ho.
SQ(i++) alag hoga: macro i++ ko do baar evaluate karta hai, inline function sirf ek baar.Ek inline function ka address & se liya ja sakta hai.
True. Ye ek real function hai jiska ek single definition hota hai, isliye
&square ek valid pointer hai; macro sirf text hai aur uska koi address nahi hota.Har macro parameter ko parentheses mein wrap karna macro ke saare dangers remove kar deta hai.
False. Parentheses precedence trap fix karte hain lekin
i++ jaisi side-effect arguments ki double-evaluation ke liye kuch nahi karte.Ek macro local variables ki scope ko usi tarah respect karta hai jaise ek function karta hai.
False. Preprocessor global text paste karta hai; ek macro accidentally surrounding scope ke names ko capture ya collide kar sakta hai kyunki usko scope ka koi notion hi nahi hota.
Kyunki ye jump avoid karta hai, ek sahi se likha hua macro hamesha ek inline function se faster hota hai.
False. Ek inlined function bhi koi call jump nahi karta, aur ye har argument ko sirf ek baar evaluate karta hai — isliye ye aksar equal ya better code produce karta hai.
Tum ek debugger mein macro ke andar ek breakpoint set karke step through kar sakte ho.
False. Preprocessing ke baad macro ka "code" call-site line mein merge ho jaata hai, isliye debuggers uske andar nahi rok sakte; inline functions debuggable rehti hain.
Preprocessor #define expand karte waqt C operator precedence samajhta hai.
False. Ye sirf tokens aur text jaanta hai;
#define BAD(x) x*x mein BAD(2+3) expand hoke 2+3*2+3 ban jaata hai, jise precedence phir 11 evaluate karta hai.C mein ek inline function ek saath int, double, aur char ke upar generic ho sakti hai.
False. C mein overloading nahi hoti, isliye ek inline function ek type signature lock karti hai; type-generic behaviour ek sachchi wajah hai macro tak pahunchne ki.
Spot the error
#define AREA(w,h) w*h — baad mein use kiya 1/AREA(2,3) ke roop mein.
Error: expand hoke
1/2*3 = 1 banta hai (hona chahiye tha 1/6). Poore body ya params ke around koi parentheses nahi; likho ((w)*(h)).#define SQ(x) ((x)*(x)) phir SQ(i++).
Error:
i++ do baar substitute hota hai → ((i++)*(i++)), isliye i do baar increment hota hai — undefined behaviour. Ek inline function i++ ko sirf ek baar evaluate karta.#define MAX(a,b) ((a)>(b)?(a):(b)) phir MAX(p++, q++).
Error: winning argument
?: ke andar do baar baith jaata hai, isliye jo bhi branch choose ho, wo do baar increment hoti hai. Fully parenthesized hone ke bawaajood, side-effect args macros mein unsafe rehte hain.#define SWAP(a,b) { int t=a; a=b; b=t; } use kiya as if (x) SWAP(p,q); else foo();.
Error:
SWAP(p,q) ke baad ka trailing ; if ko close kar deta hai, else ko orphan bana deta hai. Puri cheez ko ek statement banana ke liye do { ... } while(0) idiom use karo.#define PI 3.14; phir area = PI * r * r;.
Error: stray
; ban jaata hai area = 3.14; * r * r; — ek syntax error. Constant macros semicolon pe end nahi karni chahiye; waise bhi const prefer karo.static inline int cube(int x) { return x*x*x; } called as cube(1000000).
Error: inlining nahi —
int arithmetic silently overflow karta hai, phir bhi UB hai. Inline call problems fix karta hai, type-range problems nahi; wider type choose karo.#define DBL(x) 2*x use kiya as DBL(a+b).
Error: expand hoke
2*a+b banta hai, na ki 2*(a+b). Argument ke around parentheses missing hain; likho (2*(x)).Why questions
Kyun ek macro ki argument evaluation ko cleverer parentheses se "fix" nahi kiya ja sakta?
Kyunki parentheses sirf pasted text ki grouping change karte hain; argument text phir bhi utni baar literally appear karta hai jitni baar use kiya gaya hai, isliye uske side effects utni baar fire hote hain.
Kyun ek inline function har argument ko exactly ek baar evaluate karta hai chahe inline ho?
Language semantics har argument ko body run hone se pehle ek parameter mein compute kar dete hain; inlining already-evaluated behaviour ki copy hai, na ki re-textual paste.
Kyun inline ko speed ke bajaye linkage affect karne wala kaha jaata hai?
C mein,
inline change karta hai ki definition translation units ke across kaise emit hoti hai (one-definition rules); actual pasting optimizer pe chhodi jaati hai.Kyun hum macros padhaate hain jab inline functions safer hain?
Macros wo kaam karte hain jo functions nahi kar sakte: type-generic code, stringizing
#x, token-pasting a##b, aur conditional compilation — ye C Preprocessor ke non-function powers hain.Kyun macro trap "compiler ke shuru hone se bhi pehle" hota hai?
Text substitution preprocessing phase mein chalta hai, isliye type checking kabhi original call nahi dekhti — wo sirf already-mangled text dekhti hai, aur tumhe warn nahi kar sakti.
Kyun call overhead hatana tiny operations ke liye sabse zyada matter karta hai?
Agar kaam (jaise ek multiply) setup cost (push, jump, save, return) se chhota hai, toh overhead dominate karta hai — isliye ise eliminate karna sabse bada relative win deta hai.
Kyun do { ... } while(0) multi-statement macros ke liye sirf { ... } se better prefer kiya jaata hai?
Ek bare block phir bhi macro call ke baad ek stray
; chhodta hai jo if/else tod sakta hai; do{...}while(0) exactly ek ; swallow karta hai aur ek single statement ki tarah behave karta hai.Edge cases
Kya hota hai ek aisi macro ke saath jo zero arguments leti hai, jaise #define NOW time(0)?
Pure substitution ke liye theek hai, lekin har use
time(0) dobara run karta hai; agar tumne ek cached value expect ki thi toh surprise hoge — const/inline tumhe ek evaluation deta hai.Kya hoga agar tum ek side-effect wali function call macro mein pass karo, jaise SQ(read())?
read() do baar invoke hoga, potentially do inputs consume karke. Inline square(read()) sirf ek baar read karta hai — ye I/O ke saath double-evaluation trap hai.Kya hoga agar compiler tumhari inline function ko inline karne se inkaar kar de?
Wo overhead wale normal call par fall back karega lekin semantics bilkul correct rehenge; correctness kabhi inlining pe depend nahi karti, sirf performance.
Kya hoga agar ek macro name baad mein kisi variable name se collide kare?
Preprocessor identifier ko har jagah blindly replace kar deta hai, silently unrelated code corrupt karke — ek scope hazard jo functions nahi cause kar sakte. Convention: clashes reduce karne ke liye UPPER_CASE macro names rakho.
#define EMPTY phir EMPTY x ka result kya hoga?
EMPTY kuch nahi expand hota, sirf x bachta hai — ek object-like macro bilkul gaayab ho sakti hai, jo conditional-compilation guards ke liye intentional hai.Kya hoga agar ek macro khud apne aap ko argument ke roop mein pass kiya jaaye, jaise recursive #define?
Preprocessor apni hi expansion ke dauran same macro mein recurse nahi karta, isliye silently ruk jaata hai — unlike ek truly recursive inline function jo compiler simply inline nahi karega.
Connections
- C Preprocessor — jahan blind text substitution rehti hai
- Operator Precedence in C — upar ke parenthesis traps
- Function Call Overhead — woh cost jo dono techniques remove karte hain
- Undefined Behavior in C — double-evaluation aur overflow
- const and constexpr — constant macros ka typed alternative
- Compiler Optimization — jab
inlinehonor kiya jaata hai