Constexpr, если с условием, отличным от логического

Кажется, я нашел кое-что, в чем не согласны Clang и GCC. Вот код:

int main() {
  if constexpr (2) {}
}

Это успешно компилируется с GCC 7.4.0, но не с Clang 7.0.0 с этим сообщением об ошибке:

test.cpp:3:17: error: constexpr if condition evaluates to 2, which cannot be narrowed to type 'bool'
      [-Wc++11-narrowing]
  if constexpr (2) {}
                ^
1 error generated.

cppreference, похоже, не упоминает «сужение», так что это похоже на Clang ошибка, но я не совсем уверен. Если это ошибка любого из компиляторов, сообщалось ли об этом?


person Indiana Kernick    schedule 27.02.2019    source источник
comment
Что, если вы сделаете if constexpr (!!2) {}?   -  person Jesper Juhl    schedule 27.02.2019
comment
(!! 2) будет работать, но 2 тоже должно работать.   -  person ivan.ukr    schedule 27.02.2019
comment
Я только что проверил. !!2 работает с лязгом   -  person Indiana Kernick    schedule 27.02.2019


Ответы (2)


Clang диагностирует в соответствии с этими пунктами

[stmt.if] (выделено мной)

2 Если оператор if имеет форму if constexpr, < strong> значение условия должно быть контекстно преобразованным константным выражением типа bool; эта форма называется оператором constexpr if.

[expr.const]

4 Преобразованное постоянное выражение типа T является выражением, неявно преобразован в тип T, где преобразованное выражение является постоянным выражением, а неявная последовательность преобразования содержит только

  • интегральные преобразования, кроме сужающих преобразований,

Теперь, когда дело доходит до интегральных преобразований, преобразование в bool отображается как интегральное преобразование. И это сужает в самом строгом смысле слова, поскольку bool не может представлять все значения int. Так что диагностика не беспочвенна.

Но я думаю, что также вполне разумно принять во внимание тот факт, что преобразование в bool обычно предназначено для проверки "истинности", и поэтому его сужающий характер не имеет значения. Это похоже на небольшую ошибку в стандартном 1, где GCC идет по пути здравого смысла, а Clang придерживается сухой буквы закона в самом строгом смысле этого слова.


1 - И существует предложение по его изменению.

person StoryTeller - Unslander Monica    schedule 27.02.2019
comment
Баг в стандарте! ржу не могу - person Indiana Kernick; 27.02.2019
comment
@ Rakete1111 - бессовестно добавил в ответ :) Спасибо! - person StoryTeller - Unslander Monica; 27.02.2019

Мы говорим это, но это скрыто. «Константное выражение с контекстным преобразованием типа bool» - это стандартный термин, исключающий сужающие преобразования.

Clang правильный.

person T.C.    schedule 27.02.2019
comment
Согласилась ли CWG с тем, что нынешняя формулировка стандарта предназначена? - person Language Lawyer; 27.02.2019