Based on the template, compilation time with custom messages can only be compiled on some compilers

This code demonstrates compilation time using a template. I found that it can only be compiled with g ++ (4.4.7) with the following cmd line.

$ g++ -std=c++98 a.cpp -oa 

The void icc (13.0.1) or visual C ++ (14.00.50727.762 for 80x86) can compile it. For icc, it generates an error message like

 $ icpc a.cpp -oa a.cpp(13): error: non-integral operation not allowed in nontype template argument COMPILE_TIME_ASSERT(true && "err msg"); ^ a.cpp(13): error: class "CompileTimeAssert<<error-constant>>" has no member "Check" COMPILE_TIME_ASSERT(true && "err msg"); ^ compilation aborted for a.cpp (code 2) 

However, I found that statements like true && "err msg" are widely used at runtime as Add custom messages to assert?

Questions

  • Can this be solved without changing the code, only with the correct compilation options?
  • If it fails, do any alternative compile-time methods argue with custom messages?

The demo code is as follows.

 #include <iostream> template<bool B> class CompileTimeAssert { }; template<> class CompileTimeAssert<true> { public: static inline void Check() { } }; #define COMPILE_TIME_ASSERT(b) CompileTimeAssert<(b)>::Check() int main() { COMPILE_TIME_ASSERT(true && "err msg"); std::cout<<(true && "err msg")<<std::endl; return 0; } 
+4
source share
1 answer

The answer to the first question: "No." The argument that you pass to the template is called the so-called "non-type template argument". According to the standard, such arguments should be:

constant expressions, addresses of functions or objects with external communication, or addresses of static members of a class.

An expression like true && "err msg" strictly speaking cannot be determined at compile time. Therefore, it can be used with runtime statements, but not at compile time. g ++ demonstrates non-standard behavior here.

As an answer to the second question, I propose the following template:

 #define STATIC_ASSERT(e,m) extern char (*__static_assert_failed(void)) [ 1 - 2*!(e) ] 

__static_assert_failed here is a pointer to an external function that returns an array of characters. The array has a size of 1 - 2*!(e) , which becomes negative if e is false, causing a compile-time error.

0
source

Source: https://habr.com/ru/post/1493458/


All Articles