Question bank — Compile-time assertions — static_assert
5.1.31 · D5· Coding › C Programming › Compile-time assertions — static_assert
Shuru karne se pehle, woh ek sentence yaad karo jo in mein se zyada problems solve kar deta hai: static_assert ko compiler evaluate karta hai, isliye iska condition ek constant expression hona chahiye — ek aisi value jo program run kiye bina poori tarah se known ho.
True ya false — justify karo
C11 mein tum static_assert mein message string chhod sakte ho.
Ek passing static_assert ek tiny runtime check add karta hai jise CPU jaldi skip kar leta hai.
static_assert(1 == 1); aur assert(1 == 1); basically ek hi cheez hain.
static_assert compile time par fire karta hai aur constant chahiye; assert (<assert.h> se) run time par fire karta hai aur variables inspect kar sakta hai. Ye dono program ki life ke alag alag phases mein rehte hain.C11 mein static_assert koi bhi header include kiye bina likh sakte hain.
static_assert ek macro hai <assert.h> mein. Raw keyword _Static_assert ko koi header nahi chahiye.#error check kar sakta hai ki sizeof(int) == 4 hai ya nahi.
#error preprocessor mein run hota hai, jiske paas koi type information nahi hoti — woh sizeof evaluate nahi kar sakta. Sirf compiler (static_assert ke zariye) type sizes jaanta hai.static_assert(sizeof(int) == 4); C23 mein theek se compile hoga.
static_assert ek real keyword hai aur message optional hai, isliye akela condition legal hai. C11 ke under wahi line message na hone ki wajah se fail hoti hai.assert ko NDEBUG se compile out karna static_assert ko bhi disable kar deta hai.
NDEBUG sirf runtime assert ko silence karta hai. static_assert unaffected rehta hai — yeh koi debugging aid nahi hai jise tum band kar sako, yeh ek build gate hai.Ek function ke andar false static_assert jise tum kabhi call nahi karte, harmless hai.
Error dhundho
int n = read_config();
static_assert(n > 0, "n must be positive");::: n ek runtime variable hai, isliye n > 0 ek constant expression nahi hai — yeh compile fail kar deta hai. Runtime data ke liye assert use karo; static_assert sirf compile-time-known values ke liye hai.
// C11 source, no includes
static_assert(sizeof(long) >= 4, "long too small");::: C11 mein static_assert spelling ek macro hai — #include <assert.h> ke bina woh naam undefined hai. Fix: header include karo, ya raw keyword _Static_assert likho.
#define SIZE 100
#error (SIZE % 2 == 0) ? 0 : "SIZE must be even"::: #error expressions evaluate nahi karta — uske baad jo bhi hota hai woh sirf text hai jo unconditionally print hota hai. Even size conditionally check karne ke liye tumhe #if SIZE % 2 != 0 … #error … chahiye, ya code mein static_assert.
static_assert(strlen("hi") == 2, "wrong");::: strlen ek runtime function call hai, isliye argument ek constant expression nahi hai — yeh compile nahi hoga. Agar tumhe sach mein build time par chahiye toh sizeof("hi") - 1 use karo (ek compile-time constant, null terminator minus).
static_assert(get_flag() ? 1 : 0, "flag off");::: C mein ek function call get_flag() kabhi constant expression nahi ho sakti, isliye yeh illegal hai. Constant conditions sirf literals, sizeof, enum values, aur #defined constants se bani honi chahiyein.
enum { A = 1, B = 2 };
static_assert(A + B, "sum is zero"); // meant to catch A+B == 0::: Condition sirf value 3 hai, jo non-zero (true) hai, isliye yeh silently pass ho jaata hai aur kuch meaningful check nahi karta. Author comparison bhool gaya; unhe static_assert(A + B != 0, ...) chahiye tha.
Why questions
Condition constant kyun honi chahiye, sirf "koi bhi true expression" kyun nahi?
static_assert ka runtime cost zero kyun hai jabki assert ka thoda cost hai?
static_assert compile time par poori tarah resolve ho jaata hai aur koi code produce nahi karta; assert ek actual runtime if-check-and-abort mein compile hota hai jo har baar us line ke run hone par execute hota hai (jab tak NDEBUG se remove na ho).Usi cheez ke liye runtime check ke bajaaye static_assert(sizeof(int)==4) prefer kyun karein?
int ka size compile karte hi fix ho jaata hai — yeh kabhi per run ya per input vary nahi karta. Ek runtime check ek already-known truth ko re-verify karne mein cycles waste karega, aur ek broken binary ship ho sakti hai; compile-time check broken build ko produce karna hi impossible bana deta hai.static_assert sizeof use kar sakta hai lekin #error nahi kar sakta, kyun?
sizeof ko types ki compiler knowledge chahiye; #error preprocessor mein kaam karta hai — ek earlier phase jo sirf text tokens manipulate karta hai aur types ya sizes ke baare mein kuch nahi jaanta.static_assert(sizeof(names)/sizeof(names[0]) == COUNT) ek constant expression kyun hai?
COUNT se bina kuch run kiye compare kar sakta hai.File scope par (kisi bhi function ke bahar) static_assert rakhna kyun kaam karta hai?
static_assert ek declaration hai, isliye yeh wahan legal hai jahan koi bhi declaration ho sakti hai — file scope par, struct ke andar, ya function body ke andar. Ise koi surrounding statement ya executable context nahi chahiye.Edge cases
static_assert(0, "always here"); — kya hota hai?
static_assert(-1, "check"); — pass hoga ya fail?
0 diagnostic trigger karta hai.C11 mein static_assert(0.0 == 0.0, "float check"); — legal hai?
int (1) yield karta hai isliye yeh pass ho sakta hai, lekin floating-point constants par rely karna fragile aur non-portable hai — conditions ko integer-valued rakho.Agar same scope par do static_asserts dono false hoon, toh kaun sa message dikhega?
Ek struct ke andar static_assert false condition ke saath — kya woh phir bhi fire karega?
static_assert struct members mein appear kar sakta hai aur tab check hota hai jab type compile hoti hai — build fail hoti hai chahe us struct ka koi object abhi exist na karta ho.static_assert(sizeof(char) == 1); — kya yeh kabhi false hoga?
sizeof(char) C mein by definition 1 hai, har platform par. Isliye yeh particular assertion kabhi fail nahi ho sakta; yeh ek tautology hai, sirf intent ki documentation ke liye useful hai, real guard nahi.