我们现有的编译时断言实现基于负数组索引,它在 GCC 上提供了较差的诊断输出。C++0xstatic_assert
是一个非常好的特性,它提供的诊断输出要好得多。我知道 GCC 已经实现了一些 C++0x 特性。有谁知道是否static_assert
在其中,如果它是从什么 GCC 版本开始的?
8 回答
根据this page,gccstatic_assert
从4.3开始就有了。
如果您需要使用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 >
为了计算它的大小,这失败了,因为它没有被定义。
-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"
如果您有较旧的 gcc 或使用较旧的 C++ 标准,或使用 C,那么您可以按照此处所述模拟 static_assert:http ://www.pixelbeat.org/programming/gcc/static_assert.html
这并不能真正回答问题,但我更喜欢基于 switch-case 的编译时断言,例如
#define COMPILE_TIME_ASSERT(cond) do { switch(0) { case 0: case cond: ; } } while (0)
也可以在 C 中工作,而不仅仅是在 C++ 中。
NSPR 可以:
#define PR_STATIC_ASSERT(condition) \
extern void pr_static_assert(int arg[(condition) ? 1 : -1])
如果condition
为 false 则失败,因为它声明了一个负长度数组。
您总是可以通过模板专业化来玩弄模板和不存在的结构。据我所知,这就是 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
}
两个都
BOOST_STATIC_ASSERT(x)
BOOST_STATIC_ASSERT_MSG(x, msg)
如果您的编译器支持,将使用 C++11 static_assert