http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53638
Bug #: 53638 Summary: static_assert handling behavior ignores template specializations Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: sbrae...@knights.ucf.edu The current behavior of static_assert when inside a template definition is to detect and attempt to evaluate the assert during the parser stage, before any instantiations. (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52809) "A static_assert declaration that does not depend on template parameters will be detected and reported while parsing the template, before any instantiation. This is OK because such a template would have no valid instantiation, which immediately renders the program ill-formed." It is my opinion that this is not true. It is possible that the template might have valid specializations that occur later on in the compilation unit, making it impossible to determine whether or not it is possible to construct an instantiation of the template when parsing. The relevant part of the standard says this " Refer to 14.6p8 in the spec If no valid specialization can be generated for a template definition, and that template is not instantiated, the template deļ¬nition is ill-formed, no diagnostic required. " This seems at first to imply that the current behavior is legal. However, the current behavior evaluates the static_assert and emits a message EVEN if valid specializations CAN still be generated for a template definition. Consider this code: template<bool a> struct s { static_assert(0, "uhoh"); }; template<> struct s<false> { }; s< false > q; This should compile, because s<false> is a valid specialization of s, meaning that s<a> does not get instantiated. However, on gcc 4.5.1 and gcc 4.7, we get prog.cpp:3:5: error: static assertion failed: "uhoh" Strangely, because of this behavior, we can 'fix' it by making the constant expression dependent on a, even if we know it will always be false template<bool a> struct s { static_assert(a!=a, "uhoh" ); }; template<> struct s<false> { }; Compiles. The current behavior of GCC in this case MAY be conformant with spec, but it seems to go against the intent of the spec even if it doesn't go against the letter. It also makes it difficult to use static_assert in certain metaprogramming applications(like the example above, which could be used to evaluate if a metafunction returned true). Also, as bug 52809 demonstrates, it is confusing to users.