19

我们现有的编译时断言实现基于负数组索引,它在 GCC 上提供了较差的诊断输出。C++0xstatic_assert是一个非常好的特性,它提供的诊断输出要好得多。我知道 GCC 已经实现了一些 C++0x 特性。有谁知道是否static_assert在其中,如果它是从什么 GCC 版本开始的?

4

8 回答 8

29

根据this page,gccstatic_assert从4.3开始就有了。

于 2009-06-12T16:40:25.073 回答
18

如果您需要使用GCC不支持的版本,static_assert您可以使用:

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT( /* assertion */ )

基本上, boost 的作用是:

声明(但不要定义!)

template< bool Condition > struct STATIC_ASSERTION_FAILURE;

为断言成立的情况定义一个特化:

template <> struct STATIC_ASSERTION_FAILURE< true > {};

然后你可以像这样定义 STATIC_ASSERT:

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

诀窍是,如果 Condition 为 false,编译器需要实例化结构

STATIC_ASSERTION_FAILURE< false >

为了计算它的大小,这失败了,因为它没有被定义。

于 2009-06-12T17:01:29.920 回答
9

-std=c++0x使用标志编译时,以下代码在 g++ 4.4.0 中按预期工作:

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

它显示:

x.cpp: In function 'int main()':
x.cpp:2: error: static assertion failed: "that was false"
于 2009-06-12T16:48:20.467 回答
6

如果您有较旧的 gcc 或使用较旧的 C++ 标准,或使用 C,那么您可以按照此处所述模拟 static_assert:http ://www.pixelbeat.org/programming/gcc/static_assert.html

于 2010-05-13T10:31:56.360 回答
2

这并不能真正回答问题,但我更喜欢基于 switch-case 的编译时断言,例如

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

也可以在 C 中工作,而不仅仅是在 C++ 中。

于 2009-06-12T17:03:30.320 回答
2

NSPR 可以:

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

如果condition为 false 则失败,因为它声明了一个负长度数组。

于 2011-09-06T15:22:37.433 回答
1

您总是可以通过模板专业化来玩弄模板和不存在的结构。据我所知,这就是 boost 的作用。这就是我用作 static_assert 的方法,它非常简单。

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__  ()
}

使用示例

int main(int argc, char **argv)
{
    static_assert(sizeof(int) == 1)           // Error
    static_assert(sizeof(int) == sizeof(int)) // OK
}
于 2011-04-02T06:58:08.973 回答
0

两个都

    BOOST_STATIC_ASSERT(x)
    BOOST_STATIC_ASSERT_MSG(x, msg)

如果您的编译器支持,将使用 C++11 static_assert

于 2013-04-16T23:28:37.207 回答