Являются ли ʻinline` и `noexcept` избыточными в контексте consteval?

Я работаю с кодом, в котором constexpr используются функции, которые я в настоящее время рефакторую consteval когда возможно.

inline constexpr auto example() noexcept { /*...*/ }

Насколько я понимаю,inline ключевое слово выше уже является избыточным в constexpr функция.

Насколько я понимаю, noexcept ключевые слова являются избыточными для consteval функции, потому что я так понимаю constevalдолжен оцениваться во время компиляции и, следовательно, не подразумевает исключения. Это правда или есть что-то, что я в настоящее время не рассматриваю (например, constexprexceptions)?

consteval auto example() { /*...*/ }

1 ответ

Решение

inlineявляется избыточным, потому что: [dcl.constexpr] / 1:

Функция или статический член данных, объявленный с constexpr или consteval спецификатор неявно является встроенной функцией или переменной ([dcl.inline]).


noexceptнесколько интереснее. Это правда, что попытка выбросить исключение (будь то черезthrow, dynamic_cast, или typeid) не допускается в течение постоянного времени оценки ([expr.const]/5.24). А посколькуconstevalфункция оценивается только в течение постоянного времени оценки,noexceptимеет минимальную выгоду - исключение никогда не ускользнет из этой области. И, более того, у вас даже не может быть указателя на функцию для утечки этих функций во время выполнения. На самом деле я не могу придумать механизма, для которого это было бы актуально.

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

Тем не менее, я бы пропустил noexcept. Это определенно не приносит пользы сейчас, и, возможно, даже не принесет пользы в будущем. И если я в конечном итоге ошибаюсь, тогда... Мне очень жаль.

Хотя на самом деле, как указывает TC, все не так просто:

consteval int current() { return 1; }
void f(int, int = current()) noexcept;

Что noexcept(f(1))? Как написано, этоfalse. И это довольно странно, так как это выражениеf(1)точно не собираюсь бросать. Так что, может, тебе стоит написатьnoexcept. Хотя раз уж точно бросить нельзя, может язык должен сделатьconsteval функции noexceptпо умолчанию. Хотя, если мы сделаем это и в конечном итоге добавим исключения в течение постоянного времени оценки... теперь мы снова будем лгать, поскольку это то, что мы не сможем вернуть.

Другие вопросы по тегам