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

Почему спецификатор "noexcept" не является частью типа функции?

Я не понимаю, почему? Я не думаю, что совместимость должна быть проблемой, поскольку функции, объявленные без спецификатора, фактически неявно определяют значение false. Если это связано с именем mangling - можем ли мы предположить, что старый (существующий) будет означать noexcept (false) и добавить еще один новый символ в mangling для noexcept (true).

Это будет полезно при работе с шаблонами, поскольку теперь сравнение типа функции и спецификатора noexcept должно выполняться отдельно. В основном я имею в виду следующее:

int func() noexcept(true), func_1() noexcept(false);

decltype(func) == decltype(func_1); //this now equals true

Но, с другой стороны, если бы у нас было назначение функции с помощью указателя или ссылки, то - спецификатор noexcept проверяется, как если бы он был частью типа:

int (&refFunc)() noexcept(true) = func_1; //target exception specification is not superset of source

int (&refFunc)() noexcept(true) = func; //ok

Итак, теперь реализация полного соответствия функций должна выполняться как выполняющим типом, так и безэксплуатационной проверкой, которая является сложной:

decltype(func) == decltype(func_1) && noexcept(func()) == noexcept(func_1()); //this now equals false

Представьте, если функции получили параметры:

int func(int, double) noexcept(true), func_1(int, double) noexcept(false);

decltype(func) == decltype(func_1) && noexcept(func(int{}, double{})) == noexcept(func_1(int{}, double{})); //this now equals false
4b9b3361

Ответ 1

Начиная с С++ 17, спецификатор noexcept является частью типа функции.

Reference

Спецификация noexcept является частью типа функции и может появляются как часть любого декларатора функции. (поскольку С++ 17)

Ответ 2

Совместимость с C/С++ 03

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

Низкий уровень

Давайте подумаем, как функция работает на низком уровне. Они в основном прыгают с сохраненным (в стеке) обратным адресом. Они передают аргументы и возвращают значения также через стек (не всегда, но пусть упрощают бит). Итак, когда вы объявляете функцию, вы на самом деле говорите, сколько байт должно быть использовано из стека и сколько из них осталось на ней. Объявление функции больше всего говорит программе о том, что нужно ЭКСПЕРТНО НОРМАЛЬНО от функции. Теперь, зная, что, делают ли исключения что-либо в информации, обычно передаваемой в/из функции? Они этого не делают. И я думаю, что это основная причина, почему исключения не являются частью типа.

Редактировать:

В С++ 17 noexcept фактически стал частью системы типов, поэтому вы не можете этого сделать:

void (*p)();
void (**pp)() noexcept = &p; //error here

Обоснование этого решения, из того, что я знаю, позволяет улучшить оптимизацию.