Подтвердить что ты не робот

Все ли функции "noexcept", если исключения отключены?

Если вы отключите исключения путем компиляции с помощью -fno-exceptions, все функции считаются noexcept, например, с помощью std::move_if_noexcept, или вам еще нужно объявлять функции, не считая по этой причине?

4b9b3361

Ответ 1

-fno-exceptions не позволит вам исключать исключения, но не может исключить исключения из библиотек.

Например, следующий пример завершится из-за не пойманного исключения:

#include <vector>

int main()
{
    std::vector<int> v{1,2,3,4,5,6};

    return v.at(55);
}

Но следующий пример не будет компилироваться из-за опции -fno-exceptions:

int main()
{
    throw 22;
}

Сбой:

g++   -std=c++11 -g  -Wall -Wextra -fno-exceptions ./garbage.cpp 
./garbage.cpp: In function ‘int main()’:
./garbage.cpp:4:8: error: exception handling disabled, use -fexceptions to enable
  throw 22;

Из в этой статье, без главы:

Пользовательский код, который использует ключевые слова С++, такие как throw, try и catch, будет создавать ошибки, даже если в код пользователя включены заголовки libstdС++ и использует конструкции типа basic_iostream.


С другой стороны, noexcept отмечает метод как метод, который не генерирует исключений. Любое исключенное исключение вызовет std::terminate (см. [Except.terminate]/2 в стандарте С++).

Следующий пример:

struct A
{
    void foo() noexcept
    {
        throw 33;
    }
};

int main()
{
    A a;
    try
    {
        a.foo();
    }
    catch(...)
    {
    }
}

завершается:

terminate called after throwing an instance of 'int'
Aborted (core dumped)

В заключение: поведение совсем другое, если вы используете -fno-exceptions и когда вы отмечаете функцию как noexcept.


Хотя я компилирую весь свой проект с помощью -fno-exceptions (по другим причинам), мне все равно придется объявлять конструкторы перемещения операторами привязки для перемещения, кроме того, чтобы включить перемещение семантики для std:: move_if_noexcept?

Когда вы используете этот параметр, функции автоматически не помечены как noexcept. Вы должны сделать это вручную. Компилятору не разрешено делать такие изменения.

Если такая модификация будет разрешена, то этот пример будет выдавать разные выходы.