5.2.30 · D1 · Coding › C++ Programming › noexcept specifier
Ek exception ek tarika hai jisme ek function chillata hai "kuch galat ho gaya!" aur us chillane ko un functions tak travel karne deta hai jinhone use call kiya tha. noexcept ek single keyword hai jahan ek function promise karta hai ki yeh chillana kabhi usse bahar nahi jayega — aur agar woh promise toota, toh pura program turant kill ho jata hai.
Isse pehle ki tum parent note the `noexcept` specifier par trust karo, tumhe dekhna hoga ki ek exception actually kya hoti hai , "ek function se escape karna" kaisa dikhta hai , aur bool, template, aur std::move jaise chote words ka kya matlab hai. Yeh page unhe har ek ko zero se build karta hai, us order mein jisme woh ek dusre ke upar stack hote hain.
noexcept ki har baat is baare mein hai ki jab cheezein function calls ke beech galat hoti hain toh kya hota hai. Isliye humein pehle calls ko picture karna hoga.
Jab function main, a ko call karta hai, jo b ko call karta hai, toh computer unhe plates ki tarah stack karta hai: main bottom mein, phir a, phir b upar. Har plate ek stack frame hai — ek box jo us function ki local variables ko hold karta hai. Jab b finish hota hai, uski plate remove ho jaati hai aur hum a par wapas aa jaate hain.
Frames ke tower ko dekho. Normal return = top plate ko pop karo aur neeche continue karo. Exceptions ki poori story yeh hai: kya hoga agar hume ek error ki wajah se ek saath kaafi plates remove karni hon?
Ek exception ek signal hai jo ek function keyword throw ke saath raise karta hai yeh kehne ke liye "main continue nahi kar sakta — ek error aayi." Normally return karne ki jagah, control jump karta hai, stacked frames mein se neeche ek handler dhundhta hua.
throw aur catch
throw x; — signal x ko upar launch karo (actually: stack mein neeche main ki taraf).
try { ... } catch (...) { ... } — ek jaal . try mein code ko watch kiya jaata hai; agar uss mein se koi throw nikalti hai, toh matching catch block usse pakad leta hai aur program recover karta hai.
Figure mein, amber path follow karo. b throw karta hai. b mein koi jaal nahi hai, isliye b ka frame destroy ho jaata hai aur signal a mein drop ho jaata hai. a mein bhi koi jaal nahi — a ka frame bhi destroy ho jaata hai. Finally main mein ek catch hai, isliye signal wahan catch ho jaata hai.
Definition Stack unwinding aur escaping
Frames ko ek ek karke destroy karne ki process jab exception ek catch dhundh rahi hoti hai use stack unwinding kehte hain. Ek exception ek function se escape karti hai jab woh us function ke frame ke top se bahar nikal jaati hai bina andar catch hue.
Yeh word escape noexcept ka dil hai. Promise precisely yeh hai: "ek exception kabhi mujhse bahar nahi jayegi." Yeh nahi ki "main internally kabhi throw nahi karta" — sirf yeh ki kuch leaves nahi hoga.
Common mistake "Function ke andar ek
throw promise tod deta hai."
Kyun sahi lagta hai: tum literally ek throw dekhte ho.
Fix: Agar woh throw usi function ke andar ek try/catch se caught hai, toh kuch escape nahi hota — promise hold karta hai. Sirf escape matter karta hai. Isliye parent ka example try{throw 1;}catch(...){} ke baare mein theek hai.
Ek destructor , ~S() likha jaata hai, woh function hai jo automatically tab run hota hai jab type S ka ek object destroy hota hai — including jab unwinding ke dauran uska frame tear down hota hai. Yeh cleanup karta hai (memory free karta hai, files close karta hai).
Yeh woh danger hai jis par parent hint karta hai. Unwinding ke dauran hum pehle se ek exception carry kar rahe hain. Agar ek destructor bhi mid-unwinding throw kare, toh ab hamare paas ek saath do exceptions travel kar rahe hain — runtime choose nahi kar sakta ki kis ko follow kare, isliye language kehti hai: yeh illegal hai, std::terminate call karo. Isliye Destructors C++11 se implicitly noexcept hain.
Poore throw/catch mechanics ke liye Exception handling in C++ dekhein.
std::terminate
Ek library function jo program ko turant khatam kar deta hai — aur koi code nahi chalta, aur koi cleanup guarantee nahi hai. Yeh ek broken noexcept promise ki saza hai. std::terminate dekhein.
Intuition Recover karne ki jagah kill kyun?
Jis reason se tumne ek function ko noexcept mark kiya tha woh compiler ko throw away karne dene ke liye tha woh paperwork (tables) jo usse unwind karne ke liye chahiye tha. Isliye agar ek exception phir bhi escape karne ki koshish kare, toh often use karne ke liye koi paperwork bacha hi nahi hota . Ek hi safe action hai: sab kuch rok do.
Parent noexcept ko ek doosre role mein use karta hai: ek operator ki tarah jo ek bool return karta hai. Do words unlock karne ke liye.
bool
Ek value jo ya toh ==true ya false== hoti hai — ek haan/na ka jawab. noexcept(expr) inme se ek deta hai.
Definition Compile-time vs run-time
Run-time: jab program actually run ho raha hota hai.
Compile-time: pehle, jab compiler program build kar raha hota hai, kuch run hone se pehle.
noexcept(expr) ka jawab compile time par diya jaata hai. Compiler expr ko read karta hai lekin kabhi run nahi karta (ise unevaluated kaha jaata hai — sizeof jaise hi). Woh bas inspect karta hai: "kya isme koi operation throw kar sakta hai?"
Worked example Dono roles ek saath
void f () noexcept ; // ROLE 1: specifier — ek promise (signature ke baad)
bool b = noexcept ( f ()); // ROLE 2: operator — puchta hai "kya f() non-throwing hai?" -> true
Same keyword, do kaam. Jab tum noexcept(noexcept(x)) dekhte ho, outer promise hai, inner sawaal hai.
Kyunki yeh ek compile-time bool hai, tum ise ek constexpr variable mein store kar sakte ho aur generic code mein iske upar branch kar sakte ho.
template<class T> ek recipe hai jahan T ek placeholder hai "koi type jo tum baad mein fill karoge." Compiler har concrete T ke liye ek real function stamp out karta hai. Yeh ek swap ko int, std::string, kuch bhi ke liye kaam karne deta hai.
Humhe templates isliye chahiye kyunki ek function ko noexcept hona chahiye ya nahi yeh often T par depend karta hai — saste ints ka swap kabhi throw nahi karta, lekin ek throw-prone type ka swap kar sakta hai. Isliye conditional noexcept.
std::vector payoff, picture mein
Jab ek vector space khatam kar leta hai toh woh ek bada buffer allocate karta hai aur saare N elements transfer karne chahiye. Figure dekho: agar woh moves kare aur ek move aadhe mein throw kare, toh puraana buffer pehle se gut ho chuka hai — aadha data kho gaya, unrecoverable. Agar woh copies kare, toh originals untouched hain, isliye aadhe mein throw karne par kuch nahi khota.
Isliye vector tabhi move (fast) karta hai jab woh certain ho ki move throw nahi kar sakta — yaani jab move constructor noexcept ho. Warna woh copy karta hai (slow, safe). Yeh Strong exception guarantee preserve karta hai: ek failed operation ke baad, sab kuch exactly waise dikhta hai jaise pehle tha.
Exceptions throw and catch
Stack unwinding and escape
Destructors run during unwinding
std terminate kills on broken promise
noexcept operator returns bool
templates fill a type hole
vector move or copy choice
Har arrow ka matlab hai "left box ko samajhna zaroori hai pehle right box make sense kare." Sare raaste bottom mein parent topic ko feed karte hain.
Khud ko test karo — sirf tab reveal karo jab tum zor se jawab de chuke ho.
A stack frame is ek box jo ek function call ki local variables hold karta hai; calls ek dusre ke upar stack hote hain.
"Stack unwinding" means frames ko ek ek karke destroy karna jab ek exception neeche matching catch dhundhte hue drop hoti hai.
An exception "escapes" a function when woh function ko bina andar catch hue chhodke chali jaati hai (sirf yahi noexcept penalty trigger karta hai).
std::terminate doesprogram ko turant khatam kar deta hai bina kisi guaranteed further cleanup ke.
A bool is ek value jo ya toh true ya false hoti hai.
"Compile-time" vs "run-time" compile-time tab hota hai jab program build ho raha hota hai (run hone se pehle); run-time tab hota hai jab woh run ho raha hota hai.
noexcept(expr) as an operator evaluates expr howyeh unevaluated hai — compiler isse throwing ke liye inspect karta hai lekin kabhi run nahi karta, ek compile-time bool return karta hai.
template<class T> isek recipe jisme ek type-shaped placeholder T hai, har concrete type ke liye ek real function mein stamp hota hai.
Difference between copy and move copy duplicate karta hai (original intact); move internals steal karta hai (original gutted) — sasta.
std::vector prefers moving on reallocation only whenmove constructor noexcept ho, warna woh strong exception guarantee rakhne ke liye copy karta hai.