static_assert does not break compiling immediately
c++, c++11, static-assert, templates
Solution
There is nothing in the language that requires compilation to abort immediately, so anything you get that directly answers your question will necessarily be implementation-specific and won't avoid the instantiations on other implementations. What I think would be better is to rework your code in such a way that it doesn't have any way to continue with the instantiations. One possible way to do this is with `std::enable_if`:
#include <iostream>
#include <type_traits>
template <int x, typename = typename std::enable_if<x >= 0>::type>
struct SUM_impl
{
enum {VALUE = x + SUM_impl<x-1>::VALUE};
};
template<>
struct SUM_impl<0>
{
enum {VALUE = 0};
};
template <int x>
struct SUM
{
static_assert(x >= 0, "X must be greater or equal to 0");
enum {VALUE = SUM_impl<x>::VALUE};
};
int main()
{
std::cout << SUM<-1>::VALUE << std::endl;
return 0;
}
This way, the `static_assert` in `SUM` prints out a user-friendly message. The `enable_if` in `SUM_impl` forcibly rejects anything where `x < 0`, before the template would be instantiated, and if the template doesn't get instantiated, it cannot be instantiated recursively either.
I initially made `SUM` derive from `SUM_impl`, but not doing so (and copying its value) provides better diagnostics.
Problem
Code example: ``` template <int x> struct SUM { static_assert(x >= 0, "X must be greater or equal to 0"); enum {VALUE = x + SUM<x-1>::VALUE}; }; template<> struct SUM<0> { enum {VALUE = 0}; }; int main() { std::cout << SUM<-1>::VALUE << std::endl; return 0; } ``` Why compiler does not break compilation on first static_assert but continue work till reaching maximum instantiation depth? ``` Invoking: GCC C++ Compiler g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"src/Main.d" -MT"src/Main.d" -o "src/Main.o" "../src/Main.cpp" ../src/Main.cpp: In instantiation of ‘struct SUM<-1>’: ../src/Main.cpp:47:22: required from here ../src/Main.cpp:26:2: error: static assertion failed: X must be greater or equal to 0 static_assert(x >= 0, "X must be greater or equal to 0"); ^ ...... ../src/Main.cpp: In instantiation of ‘struct SUM<-2>’: ../src/Main.cpp: In instantiation of ‘struct SUM<-900>’: ../src/Main.cpp:27:18: recursively required from ‘struct SUM<-2>’ ../src/Main.cpp:27:18: required from ‘struct SUM<-1>’ ../src/Main.cpp:47:22: required from here ../src/Main.cpp:26:2: error: static assertion failed: X must be greater or equal to 0 ../src/Main.cpp:27:18: error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) instantiating ‘struct SUM<-901>’ enum {VALUE = x + SUM<x-1>::VALUE}; ^ ../src/Main.cpp:27:18: recursively required from ‘struct SUM<-2>’ ../src/Main.cpp:27:18: required from ‘struct SUM<-1>’ ../src/Main.cpp:47:22: required from here ../src/Main.cpp:27:18: error: incomplete type ‘SUM<-901>’ used in nested name specifier make: *** [src/Main.o] Error 1 13:04:05 Build Finished (took 6s.877ms) ``` The only problem here is that it takes a lot of time till break, and produces a lot of output. Is there a way to make this better? Used compiler: gcc version 4.8.1