Consider the following code:
template <int* > struct foo { };
int main() {
foo<(int*)42> f;
(void)f;
}
When compiling on clang 3.8.0 with -std=c++11
or -std=c++14
, the program compiles. When compiling with -std=c++1z
, it errors with:
main.cpp:4:9: error: non-type template argument is not a constant expression
foo<(int*)42> f;
^~~~~~~~
gcc 5.3.0 does not compile the code regardless of C++ mode, which I believe to be correct. What is the difference in clang between C++14 and C++1z and why does it accept the code? Did something change in C++1z that is relevant here?
Using godbolt demonstrates that in -std=c++1z
mode Clang 3.5.1 accepts the code but 3.6.0 rejects it. The changelog indicates that this version was when support for C++1z features were added, namely "Constant evaluation for all non-type template arguments". My guess is that C++11 and C++14 mode use the C++11 rules while C++1z mode uses the C++1z/latest draft rules. Of course, the fact that the program is considered valid in C++11/14 mode is a bug in of itself.
Here are some bug reports with similar (but not directly related) cases:
Bug 18043 - allow arbitrary address constant expressions as non-type template arguments as an extension
Bug 10398 - Clang won't accept a null pointer constant as a non-type template argument
Bug 10396 - clang crashes during name mangling with as non-type template parameter
Bug 9700 - Null pointer not accepted as non-type template argument
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With