Формулировка [expr.unary.noexcept] изменена в C ++ 17 .
Ранее ( n4140, 5.3. 7 оператор noexcept [expr.unary.noexcept] ), мой акцент :
Результат оператора noexcept равен false, если в потенциально оцененном контексте выражение будет содержать
(3.1) потенциально вычисляемый вызов функции, функции-члена, указателя функции или указателя на функцию-член который не имеет спецификации исключения без выброса ([exc.spec]), , если только вызов не является константным выражением ([expr.const]) ...
Сейчас 1 ( 7.6.2.6 Оператор noexcept [expr.unary.noexcept] ):
Результат оператора noexcept равен true , если только выражение не является потенциально-генерирующим ([исключением.spec]).
И затем в 14.5 Спецификации исключений [кроме.spec] :
Если объявление функции не имеет спецификатора noexcept, объявление имеет потенциально генерируемую спецификацию исключений, если только ...
, но , если только список из 14,5 (3) не перечисляет constexpr
, оставляя его как потенциально бросающий ...
1 ссылка на C ++ 17 n4659 добавлено LF в комментарии.
Тестовый код
constexpr int f(int i) { return i; }
std::cout << boolalpha << noexcept(f(7)) << std::endl;
int a = 7;
std::cout << boolalpha << noexcept(f(a)) << std::endl;
, используемый для печати ( с g cc 8.3 ):
true
false
как при компиляции с -std = c ++ 11 и -std = c ++ 2a
Однако теперь печатает тот же код ( с g cc 9.2 ):
false
false
оба при компиляции с -std = c ++ 11 и -std = c ++ 2a
Clang, кстати, очень непротиворечив, начиная с 3.4.1 и идет с:
false
false
- Каково правильное поведение для каждого spe c?
- Произошло ли реальное изменение в spe c? Если да, то в чем причина этого изменения?
- Если есть изменение в спецэффекте c, которое влияет или противоречит прошлому поведению, будет ли обычной практикой подчеркивать , что изменить и его последствия? Если изменение не выделено , может ли это означать, что это может быть недосмотр ?
- Если это действительно предполагаемое изменение, считалось ли оно исправлением ошибки, которое должно go Возвращаясь к предыдущим версиям spe c, правы ли компиляторы с обратной привязкой нового поведения к C ++ 11?
Примечание на стороне: noexcept
вычет по constexpr
функции влияет на этот трюк .