问题
Our existing compile-time assert implementation is based on negative array index, and it provides poor diagnostic output on GCC. C++0x's static_assert
is a very nice feature, and the diagnostic output it provides is much better. I know GCC has already implemented some C++0x features. Does anyone know if static_assert
is among them and if it is then since what GCC version?
回答1:
According to this page, gcc has had static_assert
since 4.3.
回答2:
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.
回答3:
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"
回答4:
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
回答5:
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++.
回答6:
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.
回答7:
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
}
回答8:
Both
BOOST_STATIC_ASSERT(x)
BOOST_STATIC_ASSERT_MSG(x, msg)
will use the C++11 static_assert if your compiler supports it
来源:https://stackoverflow.com/questions/987684/does-gcc-have-a-built-in-compile-time-assert