5.2.29 · HinglishC++ Programming

Exception safety — basic, strong, no-throw guarantees

1,839 words8 min readRead in English

5.2.29 · Coding › C++ Programming


Humein yeh chahiye kyun?

C++ exceptions almost kahin se bhi fire ho sakti hain: new throws std::bad_alloc, kisi contained type ka copy constructor throw kar sakta hai, ek comparator throw kar sakta hai. Jaise hi exception propagate hoti hai, stack unwind hota hai — local objects ke destructors run karte hain, lekin adha-khatam operation wahi ruk jaata hai.


TEEN guarantees hain kya?

Implicitly ek chautha bhi hai, sabse bura case — no guarantee: leaks, corruption, undefined behaviour. Hum yeh kabhi nahi chahte.

Figure — Exception safety — basic, strong, no-throw guarantees

HAR level kaise achieve karte hain?

Basic guarantee — RAII use karo

void basic_ok() {
    auto p = std::make_unique<Widget>();  // owns memory
    p->mutate();        // may throw
    risky();            // may throw
    // if either throws, ~unique_ptr frees the Widget. No leak.
}                       // object valid & destructible: BASIC guarantee

Yeh step kyun? unique_ptr ka destructor unwinding ke dauran run karta hai, toh koi delete skip nahi hota.

Strong guarantee — copy-and-swap

class Buffer {
    int* data; std::size_t n;
public:
    void append(const int* src, std::size_t k) {        // STRONG
        Buffer tmp(*this);          // 1. copy (may throw — original safe)
        tmp.grow_and_copy(src, k);  // 2. do risky work on tmp (may throw)
        swap(*this, tmp);           // 3. noexcept commit
    }                               // ~tmp frees old data
    friend void swap(Buffer& a, Buffer& b) noexcept {
        std::swap(a.data, b.data);
        std::swap(a.n,    b.n);
    }
};

Yeh step kyun? Steps 1 aur 2 throw kar sakte hain, lekin woh sirf tmp ko touch karte hain. Agar woh throw karein, toh *this exactly pehle jaisa hai → koi effect nahi. Step 3 throw nahi kar sakta → commit atomic hai.

No-throw guarantee — noexcept operations

void release(Resource* r) noexcept { /* free handles, never throws */ }

Ek subtle lekin crucial point: move aur strong guarantee


Worked Examples


Recall Feynman: ek 12-saal ke bacche ko samjhao

Soch lo tum ek kamra repaint kar rahe ho. Basic: agar tum beech mein ruk jaate ho, kamra abhi bhi usable hai — kuch jal nahi raha — lekin adha blue, adha white ho sakta hai. Strong: tum pehle ek spare wall panel paint karte ho; sirf jab woh perfectly ban jaata hai tab tum use instantly purani wall par snap kar dete ho. Agar tum beech mein ruk jaate ho, purani wall abhi bhi wahin hai, untouched — jaise tune start hi nahi kiya. No-throw: kaam itna simple hai (ek light switch flip karna) ki yeh kabhi galat ho hi nahi sakta. "Strong" ka trick hai: saara messy kaam ek copy par karo, phir use last safe second mein swap karo.


Active Recall

Teen exception-safety guarantees kaun si hain, weakest se strongest?
Basic (valid state, no leaks), Strong (commit-or-rollback / throw par koi effect nahi), No-throw (kabhi throw nahi karta, noexcept).
Basic guarantee thrown exception par kya promise karta hai?
Koi resource leaks nahi aur saare objects ek valid, destructible lekin unspecified state mein rehte hain; invariants hold karte hain.
Strong guarantee kya promise karta hai?
Commit-or-rollback: agar throw kare, toh operation ka koi effect nahi hota — state exactly call se pehle jaisi hoti hai.
Kaun sa idiom strong guarantee achieve karta hai aur kaise?
Copy-and-swap: throwing work ek copy par karo, phir use noexcept swap se swap karo taaki commit throw na kar sake.
Swap, destructors, aur moves noexcept kyun hone chahiye strong safety ke liye?
Copy-and-swap mein commit step throw nahi kar sakta; agar karta, toh tum ek unrecoverable half-done state mein stuck ho jaate.
Kaun si technique basic guarantee almost free mein deti hai?
RAII — stack objects ke paas owned resources stack unwinding ke dauran destructors ke zariye release hote hain.
Agar ek noexcept function throw kare toh kya hota hai?
std::terminate() immediately call hota hai; aage koi stack unwinding nahi hoti.
std::vector kuch types ke liye reallocation ke dauran move ki jagah copy kyun karta hai?
Agar move constructor noexcept nahi hai, toh mid-move throw source ko gut kar dega aur strong guarantee tod dega, isliye woh copy karta hai (std::move_if_noexcept).
Copy-and-swap assignment self-assignment automatically kyun handle karta hai?
Right-hand side copy ki jaati hai (by value) swap se pehle, toh kisi object ko khud se assign karna sirf copy karta hai phir harmlessly swap karta hai.
Guarantees ki strength ordering?
no guarantee < basic < strong < no-throw; har stronger level saare weaker wale imply karta hai.

Connections

Concept Map

triggers

runs

risks

prevented by

ranks as

ranks as

ranks as

no leaks, valid state

uses

commit or rollback

marked

trivially implies

implied by

Exception thrown mid-operation

Stack unwinding

Local destructors

Leaks, corruption, double-free

Exception safety contract

Basic guarantee

Strong guarantee

No-throw guarantee

RAII ownership

Copy-and-swap

noexcept keyword