Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reinterpret cast a template non-type parameter: clang c++14 vs c++1z

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?

like image 927
Barry Avatar asked May 18 '16 16:05

Barry


1 Answers

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

like image 50
uh oh somebody needs a pupper Avatar answered Nov 06 '22 23:11

uh oh somebody needs a pupper