Constexpr if 具有非布尔条件

Constexpr if with a non-bool condition

我似乎发现了 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 似乎没有提到 "narrowing",所以这似乎是一个 Clang 错误,但我不完全确定。如果这是任一编译器的错误,是否已经报告过?

Clang 正在根据这些段落进行诊断

[stmt.if] (emphasis mine)

2 If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted constant expression of type bool; this form is called a constexpr if statement.

[expr.const]

4 A converted constant expression of type T is an expression, implicitly converted to type T, where the converted expression is a constant expression and the implicit conversion sequence contains only

  • integral conversions other than narrowing conversions,

现在,当谈到整数转换时,转换 bool is listed as an integral conversion。从最严格的意义上讲,它正在缩小,因为 bool 不能表示 int 的所有值。所以诊断也不是没有根据。

但我认为考虑到 bool 的转换通常是为了检查 "truthiness" 这一事实也是相当合理的,因此它的缩小性质应该无关紧要。它看起来像是标准中的一个小错误1,GCC 走的是常识路线,而 Clang 在最严格的意义上遵守法律的枯燥字面。


1 - 和 a proposal exists to change it

我们说了,但它是隐藏的。 "contextually converted constant expression of type bool" 是排除缩小转换的标准术语。

Clang 是正确的。