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, но я не совсем уверен. Если это ошибка с любым из компиляторов, о ней уже сообщалось?

Ответы

Ответ 1

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

[stmt.if] (акцент мой)

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

[expr.const]

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

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

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

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


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

Ответ 2

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

Clang это правильно.