The following is valid in gcc 4.8:
class Value {
private:
static std::vector<float> compile_time_vector;
const bool compile_time_bool;
static bool f(void) {
compile_time_vector.push_back(2.3);
return true;
}
public:
template <typename type_t>
constexpr Value(const type_t& value): compile_time_bool(f()) {}
};
std::vector isn't designed to work at compile time, so exactly what kind of code is this generating? I've used the class to make sure it isn't optimized out.
This is ill-formed, but no diagnostic is required. The problem is that
f()
inconstexpr Value(const type_t& value): compile_time_bool(f())
may not appear in a constant expression for any template argument. But consider:Here, the
constexpr
ness ofbar
depends on the template argument. Therefore:A function template marked as
constexpr
can produceconstexpr
and non-constexpr
specializations, depending on the template arguments.It is probably hard or impossible to check if a function template is not
constexpr
for any set of template arguments (in the OP's case, it could be possible to see that asf()
unambiguously refers toValue::f
). Therefore, no diagnostic is required.The relevant paragraph is [dcl.constexpr]/6:
N.B. the
const
thing will be lifted in C++1y, so better mark member functions (not ctors, obviously) both as bothconstexpr
andconst
.Effectively, the program has UB. But once you instantiate the ctor in a context that requires a constant expression, your compiler should complain -- as does clang++3.4
Both compilers seem to accept your program if you use the ctor in a context where a constant expression is not required. I'd say that's an extension, but it's as hard to issue a warning in this case ("extension used, nonportable code") as to diagnose the program is ill-formed in the first place.