c++ - `static constexpr` function called in a constant expression is...an error? -
i have following code:
class myclass { static constexpr bool foo() { return true; } void bar() noexcept(foo()) { } };
i expect since foo()
static constexpr
function, , since it's defined before bar
declared, acceptable.
however, g++
gives me following error:
error: ‘static constexpr bool myclass::foo()’ called in constant expression
this is...less helpful, since ability call function in constant expression the entire point of constexpr
.
clang++
little more helpful. in addition error message stating argument noexcept
must constant expression, says:
note: undefined function 'foo' cannot used in constant expression note: declared here static constexpr bool foo() { return true; } ^
so...is two-pass-compilation problem? issue compiler attempting declare member functions in class before of them defined? (note outside of context of class, neither compiler throws error.) surprises me; intuitively, don't see reason static constexpr
member functions not useable in , constant expressions, inside class or out.
as t.c. demonstrated links in comment, standard not quite clear on this; similar problem arises trailing return types using decltype(memberfunction())
.
the central problem class members not considered declared until after class in they're declared complete. thus, regardless of fact foo
static constexpr
, declaration precedes of bar
, cannot considered "available" use in constant expression until myclass
complete.
as pointed out shafik yaghmour, there attempt within standard avoid dependency on ordering of members within class, , allowing example in original question compile introduce ordering dependency (since foo
need declared before bar
). however, there already minor dependency on ordering, because although constexpr
functions can't called inside noexcept
, noexcept
expression itself might depend on earlier declaration inside class:
class myclass { // void bar() noexcept(noexcept(foo())); // error if declared here static constexpr bool foo(); void bar() noexcept(noexcept(foo())); // no error }
(note not violation of 3.3.7, since there still one correct program possible here.)
this behavior may violation of standard; t.c. points out (in comment below) foo
here should looked in scope of whole class. both g++ 4.9.2 , clang++ 3.5.1 fail error when bar
declared first compile no errors or warnings when foo
declared first. edit: clang++ trunk-revision 238946 (from shortly before release of 3.7.0) not fail when bar
declared first; g++ 5.1 still fails.
intriguingly, following variation causes "different exception specifier" clang++ not g++:
class myclass { static constexpr bool foo2(); void bar2() noexcept(noexcept(foo2())); }; constexpr bool myclass::foo2() { return true; } void myclass::bar2() noexcept(noexcept(myclass::foo2())) { }
according error, noexcept
specification declaration of bar2
evaluates noexcept(false)
, considered mismatch noexcept(noexcept(myclasss::foo2()))
.