5.1.28 · D1 · Coding › C Programming › Macros vs inline functions
Ek macro aur ek inline function dono ek chhoti si operation ko fast banane ki koshish karte hain — uske kaam ko seedha wahan paste karke jahan tum use karte ho, kisi door ki function ko "phone" karne ki jagah. Poora topic do tarike ke pasting ke beech ek ladai hai: blind text copying (preprocessor) versus smart, type-aware copying (compiler) — aur parent note ke har trap ka karan yahi hai ki tumne kaunsa choose kiya.
Is ladai ko judge karne se pehle, tumhare paas har woh symbol hona chahiye jo parent note use karta hai. Neeche har cheez zero se build ki gayi hai: plain words → ek picture → kyun topic ko uski zaroorat hai. Upar se neeche padho; har rung neeche wale par khada hai.
Definition Source code = plain text
Tumhara .c file sirf characters in a text file hai — letters, digits, spaces, symbols jaise +, *, (, ). Computer abhi tak ise samajhta nahin . Kisi cheez ko ise translate karna hoga.
Intuition Yahan se kyun shuru karein?
Is topic ka har trap isi se aata hai ki kaun text padhta hai aur woh kitna samajhta hai . Toh define karne wala pehla symbol "text" khud hai. Ek macro tumhare code ko sirf text maanta hai. Compiler use meaningful C maanta hai. Yahi ek akela farq poora chapter hai.
Figure dekho: wahi line SQUARE(2 + 3) do baar dikhaayi gayi hai. Baayein ek haath sirf letters copy karta hai (yeh preprocessor ka nazariya hai). Daayein letters ko pehle numbers aur operations ki tarah samjha jaata hai (yeh compiler ka nazariya hai). Is picture ko poore topic ke liye dimag mein rakho — yeh sab kuch explain karta hai jo aage aata hai.
Ek first-pass tool jo tumhari file ko # se shuru hone wali lines ke liye scan karta hai aur text edits karta hai — copy, paste, replace, include — kisi bhi asli translation se pehle . Ise C meaning ke baare mein kuch pata nahin . Dekho C Preprocessor .
Woh tool jo preprocessor ke baad chalta hai, ab-edited text padhta hai, aur use machine instructions mein convert karta hai. Yeh types, scope, aur evaluation rules samajhta hai — yeh "smart helper" hai.
Intuition Topic ko dono ki zaroorat kyun hai
Parent note ka poora pipeline diagram hai: preprocessor pehle → compiler doosra . Ek macro step one mein resolve hota hai (blind); ek inline function step two mein resolve hota hai (smart). Inline functions ke har faayde ("type checking", "ek baar evaluate hona", "debuggable") sirf isliye hain kyunki woh doosre, samajhdaar stage mein rehte hain .
#define SQUARE ( x ) ((x) * (x)) // <- # ka matlab hai: preprocessor, mujhe handle karo
# decoration nahin hai. Yeh ek flag hai jo kehta hai: "yeh line pehle translator ke liye hai, doosre ke liye nahin." #define ke baad ki har cheez ek rule hai jise preprocessor literally maanta hai .
#define NAME replacement
Iska matlab hai: "Aage jahan bhi NAME dikhega, use delete karo aur wahan replacement paste karo — raw text ki tarah. " Kuch nahi aur, kuch nahi kam.
Definition Function-like macro
#define NAME(x) body
Same idea, lekin ek placeholder x ke saath. Jab tum NAME(something) likhte ho, preprocessor body paste karta hai aur usme har x ko literal text something se replace karta hai.
Figure mein arrows follow karo. x ek hole hai. Tum hole mein jo bhi text daalo woh body mein har jagah jahan x aata hai wahan stamp ho jaata hai — characters ki tarah, uncalculated. Isliye parent ka SQUARE(2 + 3) literal string ((2 + 3) * (2 + 3)) ban jaata hai: chaar characters 2 + 3 do baar, verbatim, paste ho jaate hain.
Common mistake "Macro pehle
2+3 jod leta hai, phir square karta hai."
Kyun sahi lagta hai: ek function yehi karta. Sach: preprocessor add nahin kar sakta — woh sirf letters copy karta hai. Ise pata hi nahin ki 2 + 3 ka matlab paanch hai. Addition baad mein hota hai, compiler mein, jo bhi text paste hua tha us par.
Definition Operator precedence
Ek fixed rule ki kaun si operation pehle hoti hai jab symbols milte hain. * + se zyada tightly bind karta hai, toh 2 + 3 * 2 ka matlab hai 2 + (3 * 2) = 8, na ki (2 + 3) * 2 = 10. Dekho Operator Precedence in C .
( )
Grouping force karne ka tarika, precedence ko override karke. (2 + 3) * 2 ka matlab hai "pehle add karo, phir multiply." Parentheses compiler ka instruction hai "yeh box karo pehle bahar ki kisi bhi cheez ko haath lagane se."
Intuition Macros ko parentheses mein kyun dubona padta hai
Kyunki preprocessor text ko kisi bade expression ke beech mein paste karta hai, aas-paas ke operators "andar ghus ke" pieces pakad sakte hain. Placeholder ko wrap karna — ((x) * (x)) — aisi deewarein banata hai jinhein baahri operators cross nahin kar sakte.
Figure mein #define BAD(x) x*x ke BAD(2+3) ke liye use karne ke dono trees hain. Parens ke bina pasted text 2+3*2+3 hai; precedence * ko sirf adjacent 3 aur 2 pakadne deta hai, jo galat red subtree = 11 deta hai. Parens ke saath, deewarein (2+3) ko square karne se pehle ek unit ki tarah resolve hone par majboor karti hain, jo 25 deta hai. Trap macro mein nahin hai — woh precedence mein hai jo carelessly pasted text par act kar raha hai .
x++ (post-increment)
Ek expression jo ==x ki current value use karta hai, phir x mein 1 add karta hai==. x++ do baar likhne ka matlab hai x 2 se badhta hai. "1 add karna" wala hissa side effect kehlata hai: sirf value produce karne se pare ek lasting change.
Intuition Yahan yeh kyun matter karta hai
Ek macro apna placeholder text utni baar paste karta hai jitni baar woh body mein aata hai. Agar tum use i++ lete ho, aur body x do baar use karti hai, toh i++ do baar stamp hota hai — isliye i do baar increment hota hai. Yeh parent ka double-evaluation trap hai. Dekho Undefined Behavior in C .
#define SQ ( x ) ((x) * (x))
int i = 3 ;
int r = SQ (i ++ ); // ((i++)*(i++)) ban jaata hai -> i do baar change hua
Ek inline function yeh sidestep kar leta hai kyunki argument i++ body ke chalane se pehle ek baar ek parameter mein compute ho jaata hai — ek concept jo hum section 7 mein build karte hain.
Definition Function call overhead
Function par jump karne ki chupi cost: arguments push karo, door jump karo, registers save karo, chalo, return karo, clean up karo. Ek bade function ke liye yeh cost dikhi nahin deti; x*x ke liye yeh asli kaam se zyada ho sakti hai. Dekho Function Call Overhead .
Figure do paths contrast karti hai. Baayein path ek function call karta hai: control current spot se nikal jaata hai, function tak jaata hai, aur wapas aata hai — round-trip overhead hai. Daayein path mein function ki body in place paste ho jaati hai (inlined), toh koi trip hi nahin. Dono macros aur inline functions right-hand picture ke liye koshish karte hain; woh sirf pasting karne ke liye alag translators choose karte hain.
inline
Ek keyword jo tum function ke saath lagate ho compiler ko suggest karne ke liye ki woh call site par body paste kare. Yeh zaruri hai ki yeh ek request hai, command nahin . Dekho Compiler Optimization .
static inline int square ( int x ) { return x * x; }
inline inlining force karta hai."
Kyun sahi lagta hai: word literally "inline" kehta hai. Sach: compiler mana kar sakta hai (jaise bade ya recursive functions). Yeh intent ke baare mein ek hint hai, plus linkage ke baare mein ek rule — kabhi guarantee nahin.
Compiler verify karta hai ki values apne declared kinds mein fit hoti hain — tum kisi word ko square nahin kar sakte, kisi string ko jahan int chahiye wahan pass nahin kar sakte. Macros isse bilkul skip karte hain; inline functions ise enforce karte hain.
Woh region jahan ek naam valid hai. Kisi function ka parameter x ek local variable hai jo sirf uske andar exist karta hai — woh accidentally tumhare baahri x se nahi takra sakta. Macro ka x sirf pasted text hai aur aisi koi boundary respect nahin karta.
Intuition Yeh payoff kyun hain
"Exactly ek baar evaluate hona", "type-safe", "debuggable", "ek address hai" — parent ki comparison table mein har inline advantage ek free gift hai ek asli, compiler-samjhe function ka hona jis mein genuine parameters aur scope hain. Constants ke liye typed alternative const and constexpr mein hai.
Source code is plain text
Parentheses force grouping
Macros vs inline functions
Khud test karo — daayein side cover karo.
Kya ek .c file text hai ya translation se pehle machine code? Sirf plain text — CPU ke liye meaningless jab tak translate na ho.
Kaun sa translator pehle chalta hai, preprocessor ya compiler? Preprocessor , compiler se pehle pure text edits karta hua.
#define SQ(x) ((x)*(x)) literally SQ(5) ke saath kya karta hai?Body paste karta hai x ki jagah 5 leke, jo text ki tarah ((5)*(5)) deta hai.
Kya preprocessor 2+3 calculate karta hai? Nahin — woh sirf characters copy karta hai; compiler baad mein arithmetic karta hai.
* 2+3*2+3 ke pieces kyun pakadta hai?Kyunki * ki higher precedence hai + se, toh woh addition se pehle bind karta hai.
Parentheses precedence ke saath kya karte hain? Woh grouping force karte hain, andar wale ko pehle resolve karwa kar chahe baahri operators koi bhi hon.
((i++)*(i++)) mein i++ kitni baar chalta hai?Do baar — i do baar increment hota hai, double-evaluation trap.
Function call overhead kya hai? Jumping, registers save karne, aur return karne ki cost — woh round-trip jise dono techniques hatati hain.
Kya inline ek guarantee hai? Nahin — ek request/hint jise compiler ignore kar sakta hai.
Ek real function (macro nahin) ka ek gift batao. Type checking, single argument evaluation, scope, debuggability, ya ek address hona.
Parent topic ↑
C Preprocessor — pehla translator jo text pasting karta hai
Operator Precedence in C — kyun macros mein parentheses non-negotiable hain
Function Call Overhead — woh cost jise hatane ke liye yeh techniques exist karti hain
Undefined Behavior in C — jahan double evaluation le jaati hai
const and constexpr — constant macros ke typed alternatives
Compiler Optimization — jab inline honor hota hai