Programming Pandit

c/c++/c#/Javav/Python


Latest Update

Friday, October 23, 2026

Applying Exception Handling and Complete Unit Revision

Applying Exception Handling and Complete Unit Revision

 

Learning Objectives

After completing this module, students should be able to:

•      Apply exception handling to input validation, constructors, destructors, templates and resource management.

•      Explain RAII and the three levels of exception safety.

•      Decide when exceptions are the right tool and when they are not.

•      Revise the whole unit (templates and exception handling) with comparison tables and know the C++ version of each feature.

 

1. Applying Exception Handling

Exception handling is useful whenever an operation can fail for reasons that the code cannot always prevent. The table lists common applications:

Application area

Possible exceptions

Typical response

Input validation

Invalid age, negative amount, wrong format

Report the error and ask again

Arithmetic

Division by zero, overflow

Reject the operation; show an error

Arrays and containers

Index out of range, empty stack, full queue

Throw out_of_range or a custom exception

File handling

File not found, read error, no permission

Show a message; close files; try another file

Dynamic memory

bad_alloc

Release other resources; reduce the request or end the program

Object construction

Invalid arguments, failure to acquire a resource

Throw from the constructor; the object is not created

Banking and business logic

Insufficient funds, invalid account

Cancel the transaction; leave the data unchanged

Networking and databases

Timeout, connection lost

Retry, or translate to a higher-level exception

 

1.1 Application: a bank account

A bank account must refuse invalid operations without damaging its own state. Each check throws a suitable standard exception before the balance is changed.

Program 6.1: Validation with invalid_argument and runtime_error.

#include <iostream>

#include <stdexcept>

using namespace std;

 

class BankAccount

{

private:

    double balance;

 

public:

    explicit BankAccount(double initialBalance)

    {

        if (initialBalance < 0)

            throw invalid_argument("Initial balance cannot be negative");

        balance = initialBalance;

    }

 

    void withdraw(double amount)

    {

        if (amount <= 0)

            throw invalid_argument("Withdrawal amount must be positive");

        if (amount > balance)

            throw runtime_error("Insufficient account balance");

        // state changes only after all checks

        balance -= amount;

        cout << "Withdrawal successful." << endl;

    }

 

    void displayBalance() const { cout << "Balance: " << balance << endl; }

};

 

int main()

{

    try {

        BankAccount account(5000);

        account.displayBalance();

        account.withdraw(2000);

        account.displayBalance();

        account.withdraw(5000);                  // too much: exception

        account.displayBalance();                // not executed

    }

    catch (const exception &e) {

        cout << "Transaction error: " << e.what() << endl;

    }

    cout << "Program completed." << endl;

    return 0;

}

 

Output:

Balance: 5000

Withdrawal successful.

Balance: 3000

Transaction error: Insufficient account balance

Program completed.

 

•      invalid_argument (a logic error) is used for values that are never valid; runtime_error for a condition that depends on the current state (not enough money).

•      The second withdrawal throws; displayBalance() after it is skipped, and the balance remains 3000.

•      The handler catches the common base exception by reference and prints what().

 

1.2 Exceptions in constructors

A constructor has no return value, so an exception is the only clean way to report that an object could not be created. When a constructor throws:

•      the object is not created; the code never receives a half-built object;

•      members and base classes that were already constructed are destroyed, in reverse order of construction;

•      the destructor of the class itself is not called, because the object never finished construction.

 

Program 6.2: A member throws during the construction of the enclosing object.

#include <iostream>

#include <stdexcept>

using namespace std;

 

class Part

{

    const char *name;

 

public:

    Part(const char *n, bool fail = false) : name(n)

    {

        cout << "Part " << name << ": constructor";

        if (fail) {

            cout << " -> throws" << endl;

            throw runtime_error("Part construction failed");

        }

        cout << endl;

    }

    ~Part() { cout << "Part " << name << ": destructor" << endl; }

};

 

class Machine

{

    Part a;

    Part b;

    Part c;

 

public:

    Machine() : a("A"), b("B", true), c("C")      // b's constructor throws

    {

        cout << "Machine: constructor body" << endl;

    }

    ~Machine() { cout << "Machine: destructor" << endl; }

};

 

int main()

{

    try {

        Machine m;

        cout << "Machine is ready" << endl;

    }

    catch (const exception &e) {

        cout << "Caught: " << e.what() << endl;

    }

    return 0;

}

 

Output:

Part A: constructor

Part B: constructor -> throws

Part A: destructor

Caught: Part construction failed

 

Title: Construction of Machine fails at member b: a is destroyed, c is never created, ~Machine() is not called. - Description: Construction of Machine fails at member b: a is destroyed, c is never created, ~Machine() is not called.

Figure 6.1: Construction of Machine fails at member b: a is destroyed, c is never created, ~Machine() is not called.

Important: Because ~Machine() does not run, a resource acquired in the constructor body with a raw new would be leaked if a later statement throws. Hold each resource in a member object (such as a smart pointer) that cleans itself up. This idea is called RAII (Section 1.5).

 

1.3 Exceptions and destructors

A destructor runs during normal scope exit and also during stack unwinding. If a destructor throws while another exception is already being handled, two exceptions would be active at once and C++ calls terminate(). Therefore destructors must not let exceptions escape: any operation inside that could throw must be caught inside the destructor.

Program 6.3: A destructor that is safe during stack unwinding.

#include <iostream>

#include <stdexcept>

using namespace std;

 

class Logger

{

public:

    Logger() { cout << "Object created." << endl; }

 

    // Destructors are implicitly noexcept since C++11 (written for emphasis).

    ~Logger() noexcept

    {

        try {

            // cleanup that could fail is wrapped

            cout << "Destructor: cleanup done." << endl;

        }

        catch (...) {

            // never let an exception escape from a destructor

        }

    }

};

 

int main()

{

    try {

        Logger obj;

        cout << "Throwing an exception." << endl;

        throw runtime_error("Something went wrong");

    }

    catch (const exception &e) {

        cout << "Exception caught: " << e.what() << endl;

    }

    cout << "Program continues." << endl;

    return 0;

}

 

Output:

Object created.

Throwing an exception.

Destructor: cleanup done.

Exception caught: Something went wrong

Program continues.

 

Version Note: C++11: destructors are implicitly noexcept. If a destructor does throw, terminate() is called immediately even without another active exception. In C++98/03 a destructor could throw (and the program terminated only if this happened during unwinding), but it was always bad practice.

 

1.4 Combining templates and exception handling

Generic code cannot know what values are valid for every type, but it can detect general violations such as an empty container, an invalid index or a zero divisor, and report them with exceptions.

Program 6.4: A generic division function.

#include <iostream>

#include <stdexcept>

using namespace std;

 

template <typename T>

T safeDivide(T a, T b)

{

    if (b == T{})

        throw invalid_argument("Division by zero");

    return a / b;

}

 

int main()

{

    try {

        cout << "Integer result : " << safeDivide(10, 2) << endl;

        cout << "Floating result: " << safeDivide(7.5, 2.5) << endl;

        cout << safeDivide(10, 0) << endl;

    }

    catch (const exception &e) {

        cout << "Error: " << e.what() << endl;

    }

    cout << "Program completed." << endl;

    return 0;

}

 

Output:

Integer result : 5

Floating result: 3

Error: Division by zero

Program completed.

 

T{} is the default (zero) value of any numeric type T, so b == T{} tests for a zero divisor for both int and double. The first two calls succeed (10 / 2 = 5, 7.5 / 2.5 = 3); the third throws.

Program 6.5: A safe array class template that checks the index.

#include <iostream>

#include <stdexcept>

using namespace std;

 

template <typename T, int SIZE>

class SafeArray

{

private:

    T data[SIZE];

 

public:

    T &at(int index)

    {

        if (index < 0 || index >= SIZE)

            throw out_of_range("Invalid array index");

        return data[index];

    }

};

 

int main()

{

    SafeArray<int, 3> arr;

    try {

        arr.at(0) = 10;

        arr.at(1) = 20;

        arr.at(2) = 30;

        cout << arr.at(1) << endl;

        cout << arr.at(5) << endl;               // out of range

    }

    catch (const out_of_range &e) {

        cout << "Array error: " << e.what() << endl;

    }

    return 0;

}

 

Output:

20

Array error: Invalid array index

 

Program 6.6: A generic stack that reports overflow and underflow with its own exception hierarchy.

#include <iostream>

#include <stdexcept>

#include <string>

using namespace std;

 

class StackError : public runtime_error

{

public:

    explicit StackError(const string &m) : runtime_error(m) {}

};

class StackOverflow : public StackError

{

public:

    StackOverflow() : StackError("Stack overflow") {}

};

class StackUnderflow : public StackError

{

public:

    StackUnderflow() : StackError("Stack underflow") {}

};

 

template <typename T, int SIZE>

class Stack

{

    T arr[SIZE];

    int top;

 

public:

    Stack() : top(-1) {}

 

    void push(const T &value)

    {

        if (top == SIZE - 1)

            throw StackOverflow();

        arr[++top] = value;

    }

 

    T pop()

    {

        if (top == -1)

            throw StackUnderflow();

        return arr[top--];

    }

};

 

int main()

{

    Stack<int, 2> s;

    try {

        s.push(10);

        s.push(20);

        int v = s.pop();

        cout << "Popped: " << v << endl;

        v = s.pop();

        cout << "Popped: " << v << endl;

        // underflow: exception thrown here

        v = s.pop();

        cout << "Popped: " << v << endl;

    }

    catch (const StackUnderflow &e) {

        cout << "Underflow handler: " << e.what() << endl;

    }

    catch (const StackError &e) {

        cout << "Other stack error: " << e.what() << endl;

    }

 

    try {

        s.push(1);

        s.push(2);

        s.push(3);                                  // overflow

    }

    // base class handler catches both kinds

    catch (const StackError &e) {

        cout << "StackError handler: " << e.what() << endl;

    }

    return 0;

}

 

Output:

Popped: 20

Popped: 10

Underflow handler: Stack underflow

StackError handler: Stack overflow

 

•      StackOverflow and StackUnderflow derive from StackError, which derives from runtime_error.

•      The first try block uses a specific handler for underflow; the second one uses the base handler StackError and so catches the overflow.

•      The stack functions throw instead of printing messages: the stack class does not know how the program wants to react – this is decided by the handler in the caller.

 

1.5 Resource management and RAII

RAII (Resource Acquisition Is Initialization) means that a resource such as memory, a file, a lock or a socket is acquired in the constructor of an object and released in its destructor. Since local objects are destroyed during stack unwinding, the resource is released automatically, whether the function ends normally or by an exception.

Program 6.7: A leak with a raw pointer, and automatic release with unique_ptr.

#include <iostream>

#include <memory>

#include <stdexcept>

using namespace std;

 

class Resource

{

    int id;

 

public:

    explicit Resource(int i) : id(i)

    {

        cout << "Resource " << id << " acquired" << endl;

    }

    ~Resource() { cout << "Resource " << id << " released" << endl; }

};

 

void withRawPointer()

{

    Resource *r = new Resource(1);

    throw runtime_error("failure after acquiring resource 1");

    delete r;                                  // never reached: memory leak

}

 

void withSmartPointer()

{

    unique_ptr<Resource> r(new Resource(2));   // RAII: released automatically

    throw runtime_error("failure after acquiring resource 2");

}

 

int main()

{

    try { withRawPointer(); }

    catch (const exception &e) { cout << "Caught: " << e.what() << endl; }

 

    try { withSmartPointer(); }

    catch (const exception &e) { cout << "Caught: " << e.what() << endl; }

    return 0;

}

 

Output:

Resource 1 acquired

Caught: failure after acquiring resource 1

Resource 2 acquired

Resource 2 released

Caught: failure after acquiring resource 2

 

Resource 1 is acquired with new and the delete after the throw is skipped, so “Resource 1 released” never appears: the memory is leaked. Resource 2 is owned by a unique_ptr, whose destructor runs during stack unwinding and releases it.

Version Note: unique_ptr and shared_ptr (header <memory>) were introduced in C++11. make_unique was added in C++14.

The older auto_ptr was deprecated in C++11 and removed in C++17; use unique_ptr instead.

 

1.6 Levels of exception safety

Guarantee

Meaning

Example

No-throw (noexcept)

The operation never throws

Destructors, swap of simple types, simple getters

Strong

If an exception occurs the state is exactly as before the call (commit or rollback)

Copy-and-swap assignment; transfer that rolls back

Basic

No leaks and all invariants hold, but the values may have changed

Most standard-library operations

None

Leaks or corrupted data are possible

Code that mixes raw new with throwing calls

 

Program 6.8: A money transfer with only the basic guarantee, and one with the strong guarantee.

#include <iostream>

#include <stdexcept>

using namespace std;

 

class Account

{

public:

    double balance;

    bool frozen;

    Account(double b, bool f = false) : balance(b), frozen(f) {}

 

    void withdraw(double a)

    {

        if (a > balance) throw runtime_error("Insufficient balance");

        balance -= a;

    }

    void deposit(double a)

    {

        if (frozen) throw runtime_error("Target account is frozen");

        balance += a;

    }

};

 

/* Basic guarantee only: if deposit() fails, the money has already left 'from' */

void transferBasic(Account &from, Account &to, double amount)

{

    from.withdraw(amount);

    to.deposit(amount);

}

 

/* Strong guarantee: undo the first step if the second one fails */

void transferStrong(Account &from, Account &to, double amount)

{

    from.withdraw(amount);

    try {

        to.deposit(amount);

    }

    catch (...) {

        from.deposit(amount);                  // roll back

        throw;

    }

}

 

int main()

{

    Account a(1000), b(500, true);

 

    try { transferBasic(a, b, 300); }

    catch (const exception &e) {

        cout << "Basic : " << e.what() << ", balance of a = " << a.balance

            << endl;

    }

 

    Account c(1000);

    try { transferStrong(c, b, 300); }

    catch (const exception &e) {

        cout << "Strong: " << e.what() << ", balance of c = " << c.balance

            << endl;

    }

    return 0;

}

 

Output:

Basic : Target account is frozen, balance of a = 700

Strong: Target account is frozen, balance of c = 1000

 

transferBasic withdraws first and then fails to deposit: 300 has vanished from account a (700 left). transferStrong catches the failure of the second step, restores the first (from.deposit(amount)) and rethrows with throw;, so the account still has 1000.

1.7 Application: file handling

By default C++ streams do not throw: failures set state flags such as failbit. Calling exceptions() makes a stream throw ios_base::failure instead, so file errors can be handled like any other exception.

Program 6.9: Opening a file that does not exist.

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

 

int main()

{

    ifstream file;

    // make the stream throw

    file.exceptions(ifstream::failbit | ifstream::badbit);

 

    try {

        file.open("no_such_file.txt");

        string line;

        getline(file, line);

        cout << "First line: " << line << endl;

    }

    catch (const ifstream::failure &e) {

        cout << "File error: could not open or read the file" << endl;

    }

    cout << "Program continues." << endl;

    return 0;

}

 

Output:

File error: could not open or read the file

Program continues.

 

The file is not found, so open() sets failbit and the stream throws. The text of what() is implementation-defined and is not printed.

2. Guidelines: When to Use Exceptions

Use exceptions for

Do not use exceptions for

Failures that the current function cannot handle itself

Normal, expected results (end of a loop, item not found in a search that may fail routinely)

Errors in constructors and operators, which cannot return codes

Control flow in ordinary logic

Errors that must not be ignored

Performance-critical inner loops where a failure is common

Reporting errors from library code to unknown callers

Errors that the caller can check cheaply beforehand, with a simple if

 

•      Throw exceptions by value and catch them by const reference.

•      Derive custom exceptions from std::exception.

•      Give resources to objects (RAII) so that clean-up is automatic.

•      Never let an exception leave a destructor; mark functions that cannot fail noexcept.

•      Catch only the exceptions that you can do something about.

 

3. Complete Unit Revision

3.1 Templates

Topic

Key points

Generic function

template <typename T> before a function; one definition, many instantiations

Deduction and explicit arguments

f(5) deduces T; f<double>(5) specifies it; mixed types in f(T, T) fail

Template versus overloading

Template: one generic body; overload: separate bodies. An exact ordinary function is preferred to a template

Generic class

Class with type parameters; objects need explicit arguments (Box<int>) until C++17

Out-of-class members

template <typename T> and ClassName<T>::; keep in the header

Non-type and default parameters

template <typename T, int SIZE = 5>; SIZE must be a constant

typename

Type parameter declaration; marks dependent type names

export

C++98: separate definition of templates (removed in C++11); C++20: used for modules

Power of templates

STL, specialization, compile-time computation (templates, constexpr), generic algorithms

 

3.2 Exception handling

Topic

Key points

Keywords

try monitors, throw raises, catch handles

Flow

Termination model: control continues after the handlers; the rest of the try block is skipped

Handler matching

Exact type or derived-to-base; no ordinary conversions; first match wins; catch (...) last

Propagation and unwinding

Uncaught exceptions go to the callers; local objects are destroyed in reverse order

Derived class exceptions

Derived handlers before base handlers; catch by const reference; avoid slicing

Options

Specific, general, catch-all, rethrow (throw;), recover, wrap (nested), terminate

terminate()

Default action abort(); change with set_terminate(); handler must not return

unexpected()

Legacy: violated specification; default calls terminate(); removed in C++17

uncaught_exception()

Legacy: is an exception in flight? Removed in C++20; use uncaught_exceptions()

exception, bad_exception

Base of standard exceptions with what(); bad_exception replaces unexpected exceptions

Application

Validation, constructors, templates, RAII, strong guarantee, file handling

 

3.3 Comparison of terminate(), unexpected() and uncaught_exception()

Function

Purpose

Called when

Default behaviour

Status

terminate()

Ends the program

Handling fails (no handler, noexcept violation, …)

Calls abort()

Current

unexpected()

Handles a violated specification

A function throws an unlisted exception

Calls terminate()

Removed in C++17

uncaught_exception()

Detects an active exception

Called by the program (e.g. in a destructor)

Returns true or false

Removed in C++20; replaced by uncaught_exceptions()

 

4. Which C++ Standard Does a Feature Need?

The table gives the status of each feature of this unit. Yes = part of the standard, Dep. = deprecated (still valid but should be avoided), Removed = no longer part of the standard.

Feature

C++98/03

C++11

C++14

C++17

C++20

Function and class templates

Yes

Yes

Yes

Yes

Yes

export template (separate definition)

Yes (rare)

Removed

Removed

Removed

Removed

auto return type with trailing ->

No

Yes

Yes

Yes

Yes

auto return type deduced alone

No

No

Yes

Yes

Yes

Class template argument deduction

No

No

No

Yes

Yes

Concepts (requires)

No

No

No

No

Yes

try, throw, catch

Yes

Yes

Yes

Yes

Yes

throw(T) specification

Yes

Dep.

Dep.

Removed

Removed

throw() specification

Yes

Dep.

Dep.

Dep.

Removed

noexcept

No

Yes

Yes

Yes

Yes

unexpected(), set_unexpected()

Yes

Dep.

Dep.

Removed

Removed

uncaught_exception()

Yes

Yes

Yes

Dep.

Removed

uncaught_exceptions()

No

No

No

Yes

Yes

terminate(), set_terminate(), bad_exception

Yes

Yes

Yes

Yes

Yes

exception_ptr, nested exceptions, get_terminate()

No

Yes

Yes

Yes

Yes

unique_ptr; auto_ptr

auto_ptr only

unique_ptr; auto_ptr Dep.

Yes

auto_ptr Removed

Yes

 

Note: Compilers often keep removed features as extensions, so a program may still compile in a newer mode (with warnings). The table describes the standard. To test a program against a specific standard with GCC or Clang use -std=c++98, -std=c++11, -std=c++14, -std=c++17 or -std=c++20.

 

5. Common Mistakes in This Unit

Mistake

Correction

Calling f(10, 2.5) for f(T, T)

Use explicit arguments, a cast or two type parameters

Defining template member functions in a .cpp file

Put template definitions in the header

Forgetting typename before a dependent type

Write typename Container::value_type

Base-class handler before the derived-class handler

Derived first, base next, catch (...) last

catch (exception e) by value

Use catch (const exception &e)

throw e; to rethrow

Use throw;

Expecting throw 5 to be caught as double

Handler types must match exactly

Throwing from a destructor

Catch inside; destructors are noexcept

Using raw new in code that may throw

Use unique_ptr or another RAII object

Using throw(T) or unexpected() in new code

Use noexcept; these features are removed

 

6. Self-Assessment Quiz

No.

Question

(a)

(b)

(c)

(d)

1

Which keyword starts a template declaration?

generic

template

typename

class

2

In a template parameter list, class T and typename T are:

Different

Equivalent

Valid only for classes

Valid only in C++20

3

For T add(T, T), the call add(10, 2.5):

Returns 12.5

Returns 12

Fails: conflicting deduction

Calls a specialization

4

Before C++17 an object of a class template needs:

No arguments

Explicit type arguments

A macro

A friend function

5

Inside a template, typename is used to:

Declare a variable

Mark a dependent name as a type

Throw an exception

Include a header

6

export template (C++98) was removed in:

C++03

C++11

C++17

C++23

7

Which keyword raises an exception?

try

catch

throw

raise

8

catch (...) is:

A syntax error

The catch-all handler

A rethrow

A destructor

9

A derived-class handler must appear:

After the base handler

Before the base handler

Anywhere

Outside the try block

10

Stack unwinding means:

Growing the stack

Destroying local objects while leaving functions after a throw

Sorting the stack

Printing the call stack

11

If no handler matches a thrown exception:

It is ignored

terminate() is called

The program restarts

unexpected() is called

12

unexpected() was removed from C++ in:

C++11

C++14

C++17

C++20

13

The modern replacement for throw() is:

noexcept

nothrow

catch

final

14

uncaught_exceptions() returns:

A bool

The number of exceptions in flight

A string

Nothing

15

The base class of the standard exceptions is:

error

std::exception

runtime_error

bad_alloc

16

vector::at() with a wrong index throws:

bad_alloc

out_of_range

bad_cast

length_error

17

An exception leaves a noexcept function. What happens?

It is caught by the caller

terminate() is called

It is ignored

The function is retried

18

The best way to catch a class exception is:

By value

By const reference

By void *

By static

19

Which statement rethrows the current exception?

throw e;

throw;

rethrow;

catch;

20

Which technique releases resources automatically during an exception?

goto

RAII

Global variables

Macros

 

Answer key

Q1

Q2

Q3

Q4

Q5

Q6

Q7

Q8

Q9

Q10

b

b

c

b

b

b

c

b

b

b

 

Q11

Q12

Q13

Q14

Q15

Q16

Q17

Q18

Q19

Q20

b

c

a

b

b

b

b

b

b

b

 

7. Unit Question Bank

Section A: Short-answer questions

1.      What is a template? State two advantages.

2.      What is the difference between a function template and a class template?

3.      What is the use of typename in a template? What was export used for?

4.      What are the three keywords used in exception handling?

5.      What happens when an exception is thrown but not caught?

6.      What is stack unwinding?

7.      Explain catch (...).

8.      What is the use of terminate()? What does noexcept mean?

9.      What is bad_exception?

10.  What is RAII?

 

Section B: Long-answer questions

1.      Explain generic functions with a program.

2.      Explain generic classes, non-type parameters and member functions defined outside the class.

3.      Explain the exception handling mechanism with the flow of control and a program.

4.      Explain handling of derived class exceptions and the order of handlers.

5.      Describe the options available for handling exceptions.

6.      Explain terminate(), unexpected() and uncaught_exception() with programs, and mention their status in modern C++.

7.      Explain the standard exception classes with their hierarchy.

8.      Explain how templates and exception handling can be combined in a generic stack, with a program.

9.      Discuss exception safety and RAII with examples.

 

Section C: Programming questions

1.      Write a function template to find the largest of two numbers.

2.      Write a template to swap two values.

3.      Write a class template Pair<T1, T2>.

4.      Write a generic stack class using templates.

5.      Write a program that handles division by zero using exception handling.

6.      Write a program with multiple catch blocks and a catch-all.

7.      Write a program that defines a custom exception class and uses it in a hierarchy.

8.      Write a program with a generic safe array that throws out_of_range.

9.      Write a program that shows stack unwinding with destructors.

10.  Write a program that retries invalid input in a loop.

 

8. Index of Programs and How to Compile Them

Programs

Module

Topic

Compile with

1.1–1.5

1

Generic functions

g++ -std=c++17

1.3 (auto return)

1

Needs C++14 or later

-std=c++14

concepts example

1

Constraints

-std=c++20

2.1–2.7

2

Class templates, typename, specialization, power of templates

-std=c++17 (2.3 CTAD needs C++17)

module example

2

C++20 modules

-std=c++20 -fmodules-ts

3.1–3.7

3

try, catch, propagation, unwinding

-std=c++17

4.1–4.8

4

Derived exceptions, handling options

-std=c++17 (4.7 needs C++11 or later)

5.1–5.3, 5.7–5.9

5

terminate, noexcept, uncaught_exceptions, standard exceptions

-std=c++17

5.4–5.6

5

Legacy: unexpected, bad_exception, uncaught_exception

-std=c++14

6.1–6.9

6

Applications

-std=c++17

 

Use -Wall -Wextra while compiling to see warnings. All programs were compiled and run with GCC 13, and their outputs are shown exactly as produced. A package with the source file of every program is provided separately.


No comments:

Post a Comment