Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constexpr if with a non-bool condition

I seem to have found something that Clang and GCC disagree on. Here's the code:

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

This successfully compiles with GCC 7.4.0, but it fails with Clang 7.0.0 with this error message:

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 doesn't seem to mention "narrowing", so this seems like a Clang bug, but I'm not entirely certain. If this is a bug with either compiler, has it already been reported?

like image 708
Indiana Kernick Avatar asked Feb 27 '19 06:02

Indiana Kernick


People also ask

Which is false about constexpr?

Short answer: static_assert(false) should never appear in a constexpr if expression, regardless of whether it's in a template function or whether it's in the discarded branch.

What is if constexpr?

Constexpr ifIf the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded.

What is the point of constexpr functions?

constexpr functions A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.


2 Answers

Clang is diagnosing under these paragraphs

[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,

Now, when it comes to integral conversions, a conversion to bool is listed as an integral conversion. And it is narrowing, in the strictest sense of the word, since a bool cannot represent all the values of an int. So the diagnostic is not without grounds.

But I think it's also quite reasonable to consider the fact a conversion to bool is usually intended to check for "truthiness", and so the narrowing nature of it shouldn't matter. It looks like a minor bug in the standard1, with GCC taking the common-sense route, and Clang adhering to the dry letter of the law in the strictest sense.


1 - And a proposal exists to change it.

like image 189
StoryTeller - Unslander Monica Avatar answered Sep 16 '22 14:09

StoryTeller - Unslander Monica


We say it, but it's hidden. "contextually converted constant expression of type bool" is a standard term-of-art that excludes narrowing conversions.

Clang is correct.

like image 24
T.C. Avatar answered Sep 16 '22 14:09

T.C.