5.1.31 · Coding › C Programming
static_assert ek check hai jo compiler compilation ke dauran perform karta hai , runtime mein nahi. Agar condition false hai, toh program compile hone se mana kar deta hai aur aapka error message print karta hai. Isse "fail-fast at build time" guard samjho — un assumptions ke liye jo code ke baare mein hi (type sizes, constant relationships, configuration) sach honi chahiye, na ki runtime data ke baare mein.
Intuition Check ko compile time par kyun le jaayein?
Runtime checks (assert, if) tabhi fire karte hain jab woh line execute hoti hai , ek machine par , ek input ke saath . Structural assumptions ke bugs — "ek int 4 bytes ka hai", "is array mein exactly 256 slots hain", "yeh enum aur yeh table same length mein rehte hain" — inhe har jagah, hamesha, program ke exist karne se pehle pakda jaana chahiye.
Ek runtime assert ki int 4 bytes ka hai, wasteful hai: yeh compile karte waqt hi true ya false hota hai, har run mein kabhi nahi badaltha.
static_assert ka zero runtime cost hota hai (koi machine code produce nahi karta) aur ise skip karna impossible hai (tum broken program build hi nahi kar sakte).
Slogan: "Agar kuch compile time par jaana ja sakta hai, toh usse compile time par hi check karo."
static_assert ek constant integer expression ko compile time par evaluate karta hai. Agar value zero (false) hai, toh compilation ek diagnostic message ke saath fail ho jaati hai. Agar non-zero (true) hai, toh yeh kuch nahi karta — koi code emit nahi hota.
Do historical forms jo aapko pehchanne chahiye:
Expression ek constant expression honi chahiye: literals, sizeof, enum values, #defined constants, etc. se bani — kuch bhi jo compiler program chalaye bina poori tarah evaluate kar sake.
Hamare paas "derive" karne ka koi "formula" nahi hai, lekin hum behaviour ko derive kar sakte hain — constant expression kya hoti hai isse.
Ek constant expression E ki value v translation time par known hoti hai (koi variables nahi, koi function calls nahi, koi runtime input nahi).
Compiler v compute karta hai.
Rule define karo:
compile ( E ) = { success, emit nothing error: print message, stop v = 0 v = 0
Kyunki step 2 translation ke dauran hota hai, koi instruction generate nahi hoti — assertion ka final binary mein koi footprint nahi hota. Yahi poora point hai: yeh ek gatekeeper hai, runtime guard nahi.
Worked example Worked Example 1 — type size ko guard karna
#include <assert.h>
#include <stdint.h>
static_assert ( sizeof ( int ) == 4 , "This code assumes 32-bit int" );
Yeh step kyun? Hum aage bit tricks karne waale hain jo tabhi kaam karti hain jab int exactly 4 bytes ka ho. Ek ajeeb platform par jahan sizeof(int) == 2 ho, expression sizeof(int) == 4 0 ban jaati hai → compilation ruk jaati hai message ke saath. Bug usse pehle pakda ja chuka hota hai jab koi broken binary ship kare.
Worked example Worked Example 2 — do cheezein sync mein rakhna
enum { COLOR_COUNT = 3 };
const char * names [] = { "red" , "green" , "blue" };
static_assert ( sizeof (names) /sizeof ( names [ 0 ]) == COLOR_COUNT,
"names[] and COLOR_COUNT got out of sync" );
Yeh step kyun? sizeof(names)/sizeof(names[0]) ek constant hai (array size compile time par known hai). Agar koi teammate 4th colour name add kare lekin COLOR_COUNT bump karna bhool jaaye, toh lengths mismatch ho jaayein → 4 == 3 is 0 → build fail ho jaata hai. Humne ek silent logic bug ko ek loud compile error mein badal diya.
Worked example Worked Example 3 — configuration constraint verify karna
#define BUFFER_SIZE 1024
static_assert ((BUFFER_SIZE & (BUFFER_SIZE - 1 )) == 0 ,
"BUFFER_SIZE must be a power of two" );
Yeh step kyun? x & (x-1) == 0 classic power-of-two test hai. Kyunki BUFFER_SIZE ek #defined constant hai, poora expression constant hai. 1024 ke liye: 1024 & 1023 = 0 → pass. Agar koi BUFFER_SIZE 1000 set kare, toh 1000 & 999 = 0 → build fail. Mask trick power-of-two size par depend karti hai, toh hum ise enforce karte hain.
Definition Teen "stop" mechanisms
==static_assert== → compile time par fail hota hai, ek constant condition chahiye, koi runtime cost nahi .
==assert== (<assert.h>) → run time par fail hota hai, condition mein variables ho sakte hain, NDEBUG se disable ho jaata hai .
==#error== → preprocessing ke dauran fail hota hai, sirf preprocessor tokens dekhta hai (sizeof use nahi kar sakta).
Kab check karta hai
sizeof/enums dekhta hai?
Runtime variables dekhta hai?
Final binary mein?
#error
preprocess
❌
❌
no
static_assert
compile
✅
❌
no
assert
run
✅ (aur bhi)
✅
yes (unless NDEBUG)
Common mistake "Main condition mein variable daal dunga."
int n = get_count ();
static_assert (n == 4 , "..." ); // ❌ won't compile
Kyun sahi lagta hai: yeh bilkul assert(n == 4) jaisa dikhta hai, jo perfectly legal hai. Fix yeh hai: static_assert ko ek compile-time constant chahiye — n ek runtime value hai. Runtime data ke liye plain assert use karo; static_assert ko constants ke liye reserve karo (sizeof, enums, #defines).
static_assert kyun bol raha hai ki defined nahi hai?"
Kyun sahi lagta hai: aapne C++-wala naam static_assert type kiya aur yeh "just work" karna chahiye. Fix yeh hai: C11/C17 mein, static_assert ek macro hai <assert.h> mein — aapko #include <assert.h> karna hoga, ya raw keyword _Static_assert use karna hoga. C23 mein yeh built-in keyword hai.
Common mistake "Main C11 mein message string bhool gaya."
static_assert ( sizeof ( int ) == 4 ); // ❌ error in C11/C17
Kyun sahi lagta hai: C23 (aur C++17) ne message optional kar diya, toh tutorials dono tarah dikhate hain. Fix yeh hai: C11/C17 ke under message mandatory hai — hamesha "..." supply karo.
Common mistake "Main maan leta hoon ki
static_assert runtime mein run karta hai agar condition mein arithmetic ho."
Kyun sahi lagta hai: arithmetic execution jaisi lagti hai . Fix yeh hai: jab tak har operand constant hai, compiler translation ke dauran arithmetic karta hai. Runtime mein kuch nahi hota — literally uske liye koi code nahi hota.
Recall Feynman: ek 12-saal ke bachche ko explain karo
Socho tum ek Lego model bana rahe ho instructions se jo kahti hain "yeh base exactly 4 studs wide honi chahiye ." Ek static_assert ek smart instruction sheet ki tarah hai jo tumhe build shuru hi nahi karne deti agar tumhari base 4 studs wide nahi hai — yeh tumhe setup par rok deti hai, na ki poori cheez banane ke baad jab woh gir jaaye. Check model exist hone se pehle hoti hai (compile time), toh ek baar model ban jaaye toh check ka koi cost nahi aur ise skip bhi nahi kiya ja sakta.
"STATIC = STAYS-true-at-compile-time." Agar truth program run hone se pehle fixed hai (sizes, constants, enums), toh static_ assert use karo. Agar truth is baat par depend karta hai ki run ke dauran kya hota hai, toh plain assert use karo.
static_assert apni condition kab check karta hai? (compile time par)
Uski condition kis tarah ka expression hona chahiye? (ek constant expression)
Kya yeh koi machine code produce karta hai? (nahi)
C11 mein static_assert spelling kaun sa header deta hai? (<assert.h>)
When does static_assert evaluate its condition? Compile time (translation) par, kabhi runtime mein nahi.
What must the condition of static_assert be? Ek constant integer expression (koi runtime variables/function calls nahi).
What happens if the static_assert condition is false (zero)? Compilation fail ho jaati hai aur message diagnostic ke roop mein print hoti hai.
What is the raw C11 keyword behind static_assert? _Static_assert (static_assert ek macro hai <assert.h> mein).
How much runtime cost does a passing static_assert add? Zero — koi machine code emit nahi hota.
In C11/C17, is the message argument optional? Nahi, yeh mandatory hai; C23 mein yeh optional ban gaya.
Difference between static_assert and assert? static_assert compile time par constants check karta hai; assert runtime par possibly-variable values check karta hai.
Why use static_assert instead of #error for sizeof checks? #error preprocessor mein run hota hai jo sizeof evaluate nahi kar sakta; static_assert compiler mein run hota hai jo kar sakta hai.
Give a static_assert that enforces a power-of-two size N. static_assert((N & (N-1)) == 0, "N must be power of two");
What disables assert but NOT static_assert? NDEBUG define karna assert ko disable karta hai; static_assert unaffected rehta hai.
assert (runtime assertions)
Preprocessor directives — #error and #if
Constant expressions in C
sizeof operator
Enumerations (enum)
Header <assert.h>
C11 vs C23 language features
Compilation fails with message
C11 keyword _Static_assert
C23 keyword message optional