Jean-Francois Bastien wrote:
We have this really neat and simple macro in our project: #define compile_assert(x) typedef bool COMPILE_ASSERT[(x) ? 1 : -1]
Although it does what we need and serves us well, I tried to replace it with BOOST_STATIC_ASSERT. Unfortunately this resulted in a lot of ugly warnings throughout the compile: warning: use of old-style cast
There's the following comment in the static assert header:
// Note that the argument to the assert is explicitly cast to bool using old- // style casts: too many compilers currently have problems with static_cast // when used inside integral constant expressions.
The solution would be to add even more defines to use old style or static casts depending on which compiler is used.
Right: historically this is why the header doesn't use static_cast here. Unfortunately GCC appears to be one of the compilers that chokes if you use static_cast in an integral constant expression: testing the diff below with gcc-3.4 (cygwin) results in the tests failing (where as enabling the same static_cast useage with msvc or intel does work OK). If you anyone can test this with gcc-4.x and let me know which versions might accept this patch OK that would be very useful, I'm attaching the updated static_assert.hpp as well as the diff. John. Here's the diff: Index: C:/data/boost/boost/trunk/boost/static_assert.hpp =================================================================== --- C:/data/boost/boost/trunk/boost/static_assert.hpp (revision 43667) +++ C:/data/boost/boost/trunk/boost/static_assert.hpp (working copy) @@ -28,6 +28,17 @@ # define BOOST_SA_GCC_WORKAROUND #endif +// +// If the compiler supports the use of static_cast inside an integral +// constant expression, and it issues warnings about old C style casts, +// then enable this: +// +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) +#define BOOST_STATIC_ASSERT_BOOL_CAST static_cast<bool> +#else +#define BOOST_STATIC_ASSERT_BOOL_CAST (bool) +#endif + #ifdef BOOST_HAS_STATIC_ASSERT # define BOOST_STATIC_ASSERT( B ) static_assert(B, #B) #else @@ -78,14 +89,14 @@ #elif defined(BOOST_MSVC) #define BOOST_STATIC_ASSERT( B ) \ typedef ::boost::static_assert_test<\ - sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >)>\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST ( B ) >)>\ BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) #elif defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND) // agurt 15/sep/02: a special care is needed to force Intel C++ issue an error // instead of warning in case of failure # define BOOST_STATIC_ASSERT( B ) \ typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ - [ ::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >::value ] + [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >::value ] #elif defined(__sgi) // special version for SGI MIPSpro compiler #define BOOST_STATIC_ASSERT( B ) \ @@ -100,12 +111,12 @@ #define BOOST_STATIC_ASSERT( B ) \ BOOST_STATIC_CONSTANT(int, \ BOOST_JOIN(boost_static_assert_test_, __LINE__) = \ - sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) ) + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >) ) #else // generic version #define BOOST_STATIC_ASSERT( B ) \ typedef ::boost::static_assert_test<\ - sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >)>\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >)>\ BOOST_JOIN(boost_static_assert_typedef_, __LINE__) #endif