Добавьте noexcept в не-бросающие встроенные функции, вызывающие функции C?

Я реализовал привязки С++ для некоторой библиотеки C. Библиотечные вызовы API могут терпеть неудачу, но, очевидно, ничего не могут выбросить; и мои привязки для целей этого вопроса являются встроенными.

Теперь, для большинства моих встроенных функций/методов компилятор может определить, что исключение не может быть выбрано; например, предположим, что у меня есть:

bool foo() { 
    auto result = wrapped_lib_foo(); 
    return some_constexpr_nothrow_cond(result); 
}

Я должен отмечать такие функции/методы с помощью noexcept?

Примечания:

Ответ 1

даже если wrapped_lib_foo является extern "C" функцией, компилятор не знает, что где-то в стеке wrapped_lib_foo никогда не выдается, если вы не укажете его явно.

Тогда есть также тот факт, что маркировка функции noexcept явно информирует вашу аудиторию о том, что функция не бросает.

Итак, да noexcept - хорошая идея.

Ответ 2

Я думаю, что это хорошая практика добавить "noexcept", когда вы знаете, что функция не бросает. Это связано с тем, что функция C может вызывать, если она обращается к С++.

Разрешено ли это обращение к С++ и throw, похоже, зависит от компилятора. Я проверил два компилятора:

MSVC: имеет параметр , /EHs, который:

Модель обработки исключений, которая захватывает только исключения С++ и сообщает компилятору, что функции, объявленные как extern "C", могут исключение.

Итак, если указан этот параметр, компилятор предполагает, что функция C может вызывать.

GCC: здесь документация -fexceptions:

Включить обработку исключений. Создает дополнительный код, необходимый для распространения исключения. Для некоторых целей это подразумевает, что GCC создает фрейм-фрейм информация для всех функций, которая может обеспечить значительный размер данных накладные расходы, хотя это не влияет на выполнение. Если вы не указали эта опция, GCC позволяет по умолчанию для таких языков, как С++, обычно требует обработки исключений и отключает его для языков например, C, которые обычно не требуют этого. Однако вам может потребоваться включить эту опцию при компиляции кода C, который должен взаимодействовать правильно с обработчиками исключений, написанными на С++. Вы также можете пожелать отключите эту опцию, если вы компилируете старые С++-программы, которые не используйте обработку исключений.

Итак, это означает, что при -fexceptions GCC компилирует код C, который может бросать. Обратите внимание, однако: при вызове функции C компилятор не знает, был ли скомпилирован код C с помощью -fexceptions или нет. Поэтому он должен предположить, что это было. Таким образом, он кажется, что GCC должен предположить, что код C может вызывать (другим возможным способом может быть то, что -fexception необходимо указать для кода С++, чтобы сообщить компилятору, что код C может бросать, но doc -fexceptions не говорит ничего подобного).

Примечание: для GCC, бросая из стека вызовов, где задействована функция C, работает даже без кода C, скомпилированного с -fexceptions в настоящее время.