Namespaces
Variants

try block

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Исключение, выброшенное в блоке try , может быть обработано соответствующим обработчиком.

Содержание

Синтаксис

try составной-оператор последовательность-обработчиков (1)
try ctor-initializer  (необязательно) составной-оператор последовательность-обработчиков (2)
1) Обычный блок try .
2) Блок function try block . compound-statement должен быть составным оператором, составляющим тело функции.
compound-statement - составной оператор compound statement
handler-seq - непустая последовательность handlers
ctor-initializer - список инициализации членов (только для constructors )

Обычный try блок

Обычный try блок является инструкцией .

Если исключение выбрасывается из его compound-statement , исключение будет сопоставлено с обработчиками в его handler-seq :

void f()
{
    throw 1;     // НЕ обрабатывается обработчиком ниже
    try
    {
        throw 2; // обрабатывается связанным обработчиком
    }
    catch (...)
    {
        // обрабатывает исключение 2
    }
    throw 3;     // НЕ обрабатывается обработчиком выше
}

Блок try функции

Функция try блок является особым видом тела функции .

Если исключение выбрасывается из его compound-statement или ctor-initializer (если есть), исключение будет сопоставлено с обработчиками в его handler-seq :

int f(bool cond)
{
    if (cond)
        throw 1;
    return 0;
}
struct X
{
    int mem;
    X() try : mem(f(true)) {}
    catch (...)
    {
        // обрабатывает исключение 1
    }
    X(int) try
    {
        throw 2;
    }
    catch (...)
    {
        // обрабатывает исключение 2
    }
};

Исключения, выброшенные в деструкторах объектов со статической продолжительностью хранения или в конструкторах объектов, связанных с неблочными переменными со статической продолжительностью хранения, не перехватываются блоком try функции main функции .

Исключения, выброшенные в деструкторах объектов с продолжительностью хранения потока или в конструкторах объектов, ассоциированных с неблокирующими переменными с продолжительностью хранения потока, не перехватываются блоком try функции в начальной функции потока.

(since C++11)

Выход за пределы составного-оператора обработчика handler функции с блоком try эквивалентен выходу за пределы compound - statement этой функции с блоком try , за исключением случаев, когда функция является конструктором или деструктором (см. ниже).

Конструктор и деструктор try блок

Для класса C , если тело функции его конструктора или деструктора представляет собой блок функции try , и исключение выбрасывается во время инициализации или разрушения, соответственно, подобъектов C , исключение также будет сопоставлено с обработчиками в handler-seq  блока функции try :

int f(bool cond = true)
{
    if (cond)
        throw 1;
    return 0;
}
struct X
{
    int mem = f();
    ~X()
    {
        throw 2;
    }
};
struct Y
{
    X mem;
    Y() try {}
    catch (...)
    {
        // обрабатывает исключение 1
    }
    ~Y() try {}
    catch (...)
    {
        // обрабатывает исключение 2
    }
};

Ссылка на любой нестатический член или базовый класс объекта в обработчике блока try конструктора или деструктора этого объекта приводит к неопределённому поведению.

Если return statement появляется в обработчике блока try функции конструктора, программа является некорректной.

Текущее перехваченное исключение повторно выбрасывается, если управление достигает конца обработчика блока функции try конструктора или деструктора.

Управление потоком выполнения

Составной-оператор блока try является оператором с ограниченным потоком управления :

void f()
{
    goto label;     // ошибка
    try
    {
        goto label; // OK
        label: ;
    }
    catch (...)
    {
        goto label; // ошибка
    }
}

Инструкция перехода (jump statement) ( goto , break , return , continue ) может использоваться для передачи управления за пределы try блока (включая его обработчики). При этом каждая переменная, объявленная в try блоке, будет уничтожена в контексте, непосредственно содержащем её объявление:

try
{
    T1 t1;
    try
    {
        T2 t2;
        goto label; // сначала уничтожается t2, затем t1
    }
    catch(...)
    {
        // выполняется, если при уничтожении t2 возникает исключение
    }
}
catch(...)
{
    // выполняется, если при уничтожении t1 возникает исключение
}
label: ;

Ключевые слова

try

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, являющиеся дефектными, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
CWG 98 C++98 оператор switch может передавать управление
в составной-оператор блока try
запрещено
CWG 1167 C++98 не было указано, будет ли блок try функции для деструктора
перехватывать исключения из деструкторов базовых классов или членов
такие исключения
перехватываются

Смотрите также