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;
}
Daniel
  • 8,179
  • 6
  • 31
  • 56
  • 4
    Try instantiating the first function template. – David G Oct 26 '14 at 01:14
  • @0x499602D2: with the corrected question, the first example can be instantiated (e.g. `foo<10>();`) without error. – Daniel Oct 26 '14 at 01:37
  • @Daniel: [No it can't.](http://coliru.stacked-crooked.com/a/f8f449a34a2a19da) – Lightness Races in Orbit Oct 26 '14 at 01:54
  • It's compiling fine for me with Clang. – Daniel Oct 26 '14 at 01:58
  • 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. – Yakk - Adam Nevraumont Oct 26 '14 at 02:01
  • 1
    I think clang is wrong to compile it because the [relaxed C++14 `constexpr` restrictions](http://en.m.wikipedia.org/wiki/C%2B%2B14#Relaxed_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. – David G Oct 26 '14 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. – T.C. Oct 27 '14 at 22:28

2 Answers2

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.

T.C.
  • 133,968
  • 17
  • 288
  • 421
2

They don't. Your test is flawed.

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

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 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. – Daniel Oct 26 '14 at 01:32
  • The first example is compiling fine for me with an instantiation under Clang. – Daniel Oct 26 '14 at 02:00
  • @Daniel: Then your question should be "_is_ this valid" not assuming it's invalid and asking why your one particular compiler allows it. – Lightness Races in Orbit Oct 26 '14 at 02:02