5.2.30C++ Programming

noexcept specifier

1,880 words9 min readdifficulty · medium2 backlinks

WHAT is it?

void a() noexcept;          // promises: never throws
void b() noexcept(true);    // same thing
void c() noexcept(false);   // may throw (this is also the default)
void d();                   // may throw (default)

WHY does it exist?

The old C++98 throw() did the same job but was clunky and is now deprecated/removed. noexcept replaced it.


HOW does it behave? (derive the consequences)

We don't memorise rules — we derive them from the single contract: "no exception may escape."

Why terminate and not rethrow? Because the whole point was to let the compiler skip the exception-handling tables for this function. There may literally be no unwinding info to use — so the only safe action is to stop everything.

This lets us write conditional noexcept:

template<class T>
void swap(T& a, T& b) noexcept( noexcept(T(std::move(a))) &&
                                noexcept(a = std::move(b)) );

Here the outer noexcept(...) is the specifier; the inner noexcept(...) is the operator computing the bool. "I'm noexcept exactly when moving T can't throw."

Figure — noexcept specifier

Worked examples


Common mistakes


Recall Feynman: explain to a 12-year-old

Imagine you tell your teacher: "I PROMISE I won't drop this glass of water while crossing the room." If you keep the promise, the teacher relaxes and doesn't lay down towels and mops everywhere — saving time and effort. But if you DO drop it after promising? You don't just get told off — the whole class is sent home immediately, no questions asked. noexcept is that promise about not "spilling" an exception. Keep it and the program runs leaner; break it and the program shuts down instantly.


Recall flashcards

What does the noexcept specifier promise?
That the function will not let any exception escape (propagate out) of it.
What happens if a noexcept function lets an exception escape?
std::terminate() is called immediately; the program is killed (no guaranteed unwinding).
What is noexcept shorthand for?
noexcept(true).
What is the default exception specification for an ordinary function?
noexcept(false) — it may throw.
What does the noexcept(expr) operator return?
A compile-time bool: true if expr is guaranteed not to throw, else false. expr is unevaluated.
Why does std::vector care if a type's move constructor is noexcept?
If move is noexcept it moves elements on reallocation (fast); otherwise it copies them to preserve the strong exception guarantee (slow).
Difference between the noexcept specifier and the noexcept operator?
Specifier (after a signature) makes a promise; operator noexcept(x) evaluates to a bool. Same keyword, two roles.
Are destructors noexcept by default since C++11?
Yes — implicitly noexcept; throwing from one calls terminate.
Does throwing and catching an exception inside a noexcept function violate it?
No — only an exception that escapes the function triggers terminate.
What old feature did noexcept replace?
The C++98 dynamic exception specification throw() (now deprecated/removed).
Write a conditional noexcept based on T's move.
void f() noexcept(noexcept(T(std::move(t))));

Connections

  • Exception handling in C++try/catch/throw mechanics this builds on
  • Move semantics — why noexcept move ctors unlock fast reallocation
  • std::vector — uses move_if_noexcept during growth
  • Strong exception guarantee — the safety level noexcept helps maintain
  • Destructors — implicitly noexcept since C++11
  • std::terminate — what fires on a broken promise
  • constexpr — both noexcept-operator and constexpr are compile-time evaluated

Concept Map

has two forms

has two forms

declares

if violated

yields

enables

enables

so vector can

keeps

deprecated, replaced by

unevaluated like sizeof

noexcept C++11

Contract: never throws

Specifier: f noexcept

Operator: noexcept expr

Compile-time bool

std::terminate

Performance

vector prefers move

Strong exception guarantee

Conditional noexcept

C++98 throw

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, noexcept ek promise hai jo tum compiler ko dete ho: "Yeh function kabhi exception bahar nahi nikalne dega." Agar tum yeh promise nibhate ho, to compiler khush ho jaata hai — woh extra cleanup machinery (unwinding tables) skip kar deta hai, jisse code fast aur leaner ban jaata hai. Lekin agar tumne promise toda — yaani noexcept function ke andar se koi exception escape ho gaya — to program politely error nahi deta, woh seedha std::terminate() call karke turant mar jaata hai. Koi catch nahi chalega. Isliye noexcept sirf tab lagao jab tum sach mein guarantee de sakte ho.

Ek important baat: noexcept ke do roop hain. Ek specifiervoid f() noexcept; — yeh promise wala hai. Doosra operatornoexcept(x) — yeh compile-time pe ek bool deta hai, true agar x throw nahi karega. Conditional noexcept mein dono ek saath aate hain: noexcept(noexcept(...)) — bahar wala promise, andar wala check.

Yeh matter kyun karta hai? std::vector jaise containers ka asli faayda yahin hai. Jab vector grow hota hai, usse purane elements naye memory mein le jaane padte hain. Agar tumhare type ka move constructor noexcept hai, to vector elements ko move karega (fast). Agar nahi, to woh copy karega (slow) taaki strong exception guarantee bani rahe — kyunki agar move beech mein throw kar de to data corrupt ho sakta hai. Matlab ek chhota sa keyword tumhare vector ki speed double kar sakta hai. Aur ek aur point: destructors C++11 se by default noexcept hote hain, to destructor mein throw mat karna warna terminate pakka.

Go deeper — visual, from zero

Test yourself — C++ Programming

Connections