http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61039
Bug ID: 61039 Summary: Using a constexpr's address as a template variable produces an unnecessary warning Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: lists at coryfields dot com Tangentially related to bug #51440 and #52036. Present in 4.7-4.9. Using the address of a non-type constexpr variable in the global namespace (or specified namespace) as a template parameter produces the following warning: test.h:14:8: warning: 'child1' has a base 'charptrbase<((const char*)(& chararray))>' whose type uses the anonymous namespace struct child1 : public charptrbase<chararray> Marking the constexpr as extern eliminates the warning, but I don't believe that should be necessary for c++11. Use of the constant itself rather than the address does not show the issue. Preprocessed source for an offending example is very short, so I'll paste below rather than attaching. The int parameter gives no warning, but the int* and const char* do. Clang compiles and gives the following warning when -Wc++98-compat is enabled, which leads me to believe that this is a subtle c++11 gcc bug: ./test.h:14:36: warning: non-type template argument referring to object 'chararray' with internal linkage is incompatible with C++98 [-Wc++98-compat] struct child1 : public charptrbase<chararray> preprocessed source follows: -- # 1 "test.cpp" # 1 "/home/cory/dev//" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 30 "/usr/include/stdc-predef.h" 3 4 # 1 "/usr/include/x86_64-linux-gnu/bits/predefs.h" 1 3 4 # 31 "/usr/include/stdc-predef.h" 2 3 4 # 1 "<command-line>" 2 # 1 "test.cpp" # 1 "test.h" 1 constexpr const int intval = 0; constexpr const char chararray[] = "test"; template<const char*> struct charptrbase {}; template<const int*> struct intptrbase {}; template<int> struct intbase {}; struct child1 : public charptrbase<chararray> {}; struct child2 : public intptrbase<&intval> {}; struct child3 : public intbase<intval> {}; # 2 "test.cpp" 2 int main() { child2 foo; (void)foo; return 0; }