Consider the following example (snippet (0)):
struct X
{
constexpr int get() const { return 0; }
};
void foo(const X& x)
{
constexpr int i = x.get();
}
int main()
{
foo(X{});
}
The above example compiles with all versions of g++ prior to g++ 10.x, and never compiled under clang++. The error message is:
error: 'x' is not a constant expression 8 | constexpr int i = x.get(); |
The error kind of makes sense, as x is never a constant expression in the body of foo, however:
X::get()is markedconstexprand it does not depend on the state ofx;Changing
const X&toconst Xmakes the code compile with every compiler (on godbolt.org) snippet (1).
It gets even more interesting when I mark X::get() as static ((on godbolt.org) snippet (2)). With that change, all tested versions of g++ (including trunk) compile, while clang++ still always fail to compile.
So, my questions:
Is
g++ 9.xcorrect in accepting snippet (0)?Are all compilers correct in accepting snippet (1)? If so, why is the reference significant?
Are
g++ 9.xandg++ trunkcorrect in accepting snippet (2)?