I'm trying to figure out whether GCC or Clang interpret the C++17 standard differently / wrong here.
This is my code, which does compile using GCC 8, but not using Clang 6:
struct BoolHolder {
constexpr static bool b = true;
};
template<bool b>
class Foo {};
int main() {
BoolHolder b;
Foo<b.b> f; // Works
BoolHolder & br = b;
Foo<br.b> f2; // Doesn't work
}
I wonder why that is. Obviously, b.b
is a valid constexpr (or the first Foo<b.b>
wouldn't be valid). Is br.b
not a valid constexpr? Why? The object or the reference itself should have nothing to do with it, since we're accessing a static constexpr member here, right?
If this is really not valid C++17, should the fact that GCC doesn't even warn me (even though I enabled -Wall -Wextra -pedantic
) be considered a bug?
Clang is correct. References are evaluated "eagerly" in constant expressions, so to speak. [expr.const]/2.11:
An expression
e
is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
- [...]
- an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either
- it is initialized with a constant expression or
- its lifetime began within the evaluation of
e
;- [...]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With