2

Using C++14. Why will this compile:

template<unsigned N>
constexpr bool foo()
{
    std::array<char, N> arr;
    return true;
}

but not this?

constexpr bool foo()
{
    std::array<char, 10> arr; // Non-constexpr constructor 'array' cannot be used in a constant expression
    return true;
}
7
  • 4
    Try instantiating the first function template. Commented Oct 26, 2014 at 1:14
  • @0x499602D2: with the corrected question, the first example can be instantiated (e.g. foo<10>();) without error. Commented Oct 26, 2014 at 1:37
  • 2
    @Daniel the existence of a C++ compiler that will compile some bit of code is not strong evidence that the code is valid C++, especially with relatively new C++14 features. Commented Oct 26, 2014 at 2:01
  • 1
    I think clang is wrong to compile it because the relaxed C++14 constexpr restrictions allow variable declarations iff those declarations contain initializers. I don't think gcc has this C++14 feature yet however as its error message corresponds to the C++11 standard. Commented Oct 26, 2014 at 15:13
  • 1
    Which version of clang are you using? It doesn't compile for me with 3.4.1. It compiles on 3.5 but not if you try to use it in a context that requires a constant expression. Commented Oct 27, 2014 at 22:28

2 Answers 2

7

§7.1.5 [dcl.constexpr]/p6:

If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is ill-formed; no diagnostic required.

It is valid for constexpr function templates to have some specializations that do not satisfy the constexpr requirements, and it is valid to use those specializations as long as they are not in a context that requires a constant expression.

It isn't valid, however, if no specialization of the template could satisfy constexpr requirements. Since in the general case it is impossible to determine whether all possible instantiations of a function template will fail to satisfy the constexpr requirements,the standard doesn't require a diagnostic. Hence, your code is ill-formed with no diagnostic required - the compiler can, but is not required to, report an error.

Sign up to request clarification or add additional context in comments.

2 Comments

How does his code not satisfy constexpr requirements?
@0x499602D2 It defines a variable of type std::array<char, N>, for which no initialization is performed.
2

They don't. Your test is flawed.

The problem is not detected until you actually attempt to instantiate the broken function template.

3 Comments

Apologies, I'd made an error in the original question. Your answer was originally of course correct, but I don't think the question would be very helpful as it was, so I've corrected it.
The first example is compiling fine for me with an instantiation under Clang.
@Daniel: Then your question should be "is this valid" not assuming it's invalid and asking why your one particular compiler allows it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.