Does GCC have a built-in compile time assert?

被刻印的时光 ゝ 提交于 2019-11-30 11:16:19

According to this page, gcc has had static_assert since 4.3.

If you need to use a gcc version which does not support it you can use

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT( /* assertion */ )

Basically, what boost does is this:

Declare (but don't define!) a

template< bool Condition > struct STATIC_ASSERTION_FAILURE;

Define a specialization for the case that the assertion holds:

template <> struct STATIC_ASSERTION_FAILURE< true > {};

Then you can define STATIC_ASSERT like this:

#define STATIC_ASSERT(Condition) \ 
  enum { dummy = sizeof(STATIC_ASSERTION_FAILURE< (bool)(Condition) > }

The trick is that if Condition is false the compiler needs to instantiate the struct

STATIC_ASSERTION_FAILURE< false >

in order to compute its size, and this fails since it is not defined.

The following code works as expected with g++ 4.4.0 when compiled with the -std=c++0x flag:

int main() {
    static_assert( false, "that was false" );
}

it displays:

x.cpp: In function 'int main()':
x.cpp:2: error: static assertion failed: "that was false"

If you have an older gcc or use an older C++ standard, or use C, then you can emulate static_assert as described here: http://www.pixelbeat.org/programming/gcc/static_assert.html

NSPR does:

#define PR_STATIC_ASSERT(condition) \
    extern void pr_static_assert(int arg[(condition) ? 1 : -1])

which fails if condition is false because it declares an array of negative length.

This doesn't really answer the question, but I like compile-time asserts based on switch-case better, e.g.

#define COMPILE_TIME_ASSERT(cond) do { switch(0) { case 0: case cond: ; } } while (0)

Works also in C and not only in C++.

you can always play around with templates and non-existant strutures via template-specialization. This is how boost does it as far as I know. This is what I use as a static_assert, it's pretty straight forward.

namespace Internal 
{
template<bool x> struct SASSERT_F;
template<      > struct SASSERT_F <true> {};
template<int  x> struct SASSERT_P        {};
#define STATIC_ASSERT(B)            \
     typedef Internal::SASSERT_P <( \
     sizeof (Internal::SASSERT_F <( \
         ((B)? true : false))    >) \
                                 )> \
         StaticAssert##__LINE__  ()
}

Example Of Use

int main(int argc, char **argv)
{
    static_assert(sizeof(int) == 1)           // Error
    static_assert(sizeof(int) == sizeof(int)) // OK
}

Both

    BOOST_STATIC_ASSERT(x)
    BOOST_STATIC_ASSERT_MSG(x, msg)

will use the C++11 static_assert if your compiler supports it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!