Re: [Boost-users] Ugly warnings from BOOST_STATIC_ASSERT
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. JF
Jean-Francois Bastien skrev:
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.
I just wonder for how long time Boost has to maintain compatibility with every buggy compiler that was ever released? Has not static_cast been an ISO standard for like a decade now? And it is not extremely difficult to implement either (unlike the export keyword). I suppose we will just continue to use our one-liner compile_assert (quoted above) for now. It seems to work on all our target platforms (GCC, MacOS X, N800, MinGW, MSVC8).
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
On Tue, Mar 18, 2008 at 6:31 PM, John Maddock
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.
Hi!, hope this help:
ricardo@miles:~/devel$ cat foo_static.cpp
#include
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
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Ricardo Muñoz Warp Networks S.L. http://www.warp.es
John Maddock skrev:
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.
Here is my test. 1. Execute "mkdir static_assert; cd static_assert". 2. Save your attached file static_assert.hpp there. 3. Create the test file prov.cc there. The rest of the test results follow as console output (where "static_assert $ " is the prompt): static_assert $ cat --number prov.cc 1 #include "static_assert.hpp" 2 BOOST_STATIC_ASSERT(1 < 2); 3 BOOST_STATIC_ASSERT(1 > 2); static_assert $ LANG="" g++-4.1.2 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: parse error in template argument list prov.cc:3: error: template argument 1 is invalid prov.cc:3: error: expected unqualified-id at end of input static_assert $ LANG="" g++-4.2.3 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: parse error in template argument list prov.cc:3: error: template argument 1 is invalid As you can see, it fails at line 3 as it should, while not complaining about line 2. It will not complain about any old-style-cast either. So the test was completely successful.
Erik wrote:
John Maddock skrev:
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.
Here is my test. 1. Execute "mkdir static_assert; cd static_assert". 2. Save your attached file static_assert.hpp there. 3. Create the test file prov.cc there.
The rest of the test results follow as console output (where "static_assert $ " is the prompt): static_assert $ cat --number prov.cc 1 #include "static_assert.hpp" 2 BOOST_STATIC_ASSERT(1 < 2); 3 BOOST_STATIC_ASSERT(1 > 2); static_assert $ LANG="" g++-4.1.2 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: parse error in template argument list prov.cc:3: error: template argument 1 is invalid prov.cc:3: error: expected unqualified-id at end of input static_assert $ LANG="" g++-4.2.3 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: parse error in template argument list prov.cc:3: error: template argument 1 is invalid
As you can see, it fails at line 3 as it should, while not complaining about line 2. It will not complain about any old-style-cast either. So the test was completely successful.
Hardly that successful: those error messages are awful! The whole point of BOOST_STATIC_ASSERT is to provide semi-readable error messages - at least so that you know it's a static assertion failure and not some other issue that's the problem. I'll have another look at this when I have a chance. John.
John Maddock wrote:
I'll have another look at this when I have a chance.
Following this up: our regression tests fail with gcc-4.1.0 on Suse Linux when I insert an explicit static_cast in there :-( So unless someone has an alternative fix, I'm stumped at present... John.
John Maddock skrev:
John Maddock wrote:
I'll have another look at this when I have a chance.
Following this up: our regression tests fail with gcc-4.1.0 on Suse Linux when I insert an explicit static_cast in there :-(
So unless someone has an alternative fix, I'm stumped at present...
How about something like this: #if __SOME_BROKEN_PLATFORM__ #define BOOST_STATIC_ASSERT whatever workaround is needed #elsif __SOME_OTHER_BROKEN_PLATFORM__ #define BOOST_STATIC_ASSERT whatever workaround is needed . . . #else #define BOOST_STATIC_ASSERT typedef bool STATIC_ASSERT_FAILURE[(x) ? 1 : -1] #endif
Erik wrote:
John Maddock skrev: How about something like this:
#if __SOME_BROKEN_PLATFORM__ #define BOOST_STATIC_ASSERT whatever workaround is needed #elsif __SOME_OTHER_BROKEN_PLATFORM__ #define BOOST_STATIC_ASSERT whatever workaround is needed . . . #else #define BOOST_STATIC_ASSERT typedef bool STATIC_ASSERT_FAILURE[(x) ? 1 : -1] #endif
Well, because that was about the very first thing that was proposed for this utility and it got rejected for reasons that are lost in the mists of time now :-( We had an unreasonably long discussion about static assert and how to implement it that I'd rather not re-visit if possible. However, the attached seems to work OK and fix the warning, can you double check where you are? John.
John Maddock skrev:
However, the attached seems to work OK and fix the warning, can you double check where you are?
$ cat --number prov.cc 1 #include "static_assert.hpp" 2 BOOST_STATIC_ASSERT(1 < 2); 3 BOOST_STATIC_ASSERT(1 > 2); $ LANG="" g++-4.1.2 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>' $ LANG="" g++-4.2.3 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
I'm currently trying to make some generic adaptator between a large numbers of legacy code and a library of mine that provides a simple way of distributing code over cluster's nodes. A classic example (in fatc the simplest one ) is that : 1/ users have a library of compiled function with prototype like some_type func(const some_other_type& x, const some_another type& y, const yet_another_type& z ); 2/ my library awaits functor with the following prototype void operator()( const some_other_type& x, const some_another type& y, const yet_another_type& z, some_type& out ); Now combine this with function using non-const reference or pointer as argument to return more than one results or functions having either arguments or alwasy returning void. There is no cap on # of arguments. I was thinking to find a way to detect the return type of any "free function" pointer from the user library and detecting its arguments type, build the corresponding function object and assign it with the user function pointer before passsing it to my own code. Basically, making this code float some_func( const float& f ); floatoutput; float input run( pipeline(seq(some_func),seq(some_func)) )(input)(output); build a 2 staegs pipeline (thsi is already done) that somehow use the boost::function wrapper around the free function as callable entity, making seq able to do all the grunt work of findidng the correct boost::function<> type. Does it seems viable or I am making some wrong assumptions on the capabilities of boost::functions ? Thanks for your insight -- Joel FALCOU Research Engineer @ Institut d'Electronique Fondamentale Université PARIS SUD XI France
John Maddock skrev:
Erik wrote:
John Maddock skrev:
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.
Here is my test. 1. Execute "mkdir static_assert; cd static_assert". 2. Save your attached file static_assert.hpp there. 3. Create the test file prov.cc there.
The rest of the test results follow as console output (where "static_assert $ " is the prompt): static_assert $ cat --number prov.cc 1 #include "static_assert.hpp" 2 BOOST_STATIC_ASSERT(1 < 2); 3 BOOST_STATIC_ASSERT(1 > 2); static_assert $ LANG="" g++-4.1.2 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: parse error in template argument list prov.cc:3: error: template argument 1 is invalid prov.cc:3: error: expected unqualified-id at end of input static_assert $ LANG="" g++-4.2.3 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: parse error in template argument list prov.cc:3: error: template argument 1 is invalid
As you can see, it fails at line 3 as it should, while not complaining about line 2. It will not complain about any old-style-cast either. So the test was completely successful.
Hardly that successful: those error messages are awful! The whole point of BOOST_STATIC_ASSERT is to provide semi-readable error messages - at least so that you know it's a static assertion failure and not some other issue that's the problem.
That is a good point. We actually get such a semi-readable error message with our current compile_assert: $ cat --number prov.cc 1 #define compile_assert(x) typedef bool COMPILE_ASSERT[(x) ? 1 : -1] 2 compile_assert(1 < 2); 3 compile_assert(1 > 2); $ LANG="" g++-4.1.2 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: size of array 'COMPILE_ASSERT' is negative $ LANG="" g++-4.2.3 -Wall -Wextra -Wold-style-cast -c prov.cc prov.cc:3: error: size of array 'COMPILE_ASSERT' is negative
John Maddock wrote:
... As you can see, it fails at line 3 as it should, while not complaining about line 2. It will not complain about any old-style-cast either. So the test was completely successful.
Hardly that successful: those error messages are awful! The whole point of BOOST_STATIC_ASSERT is to provide semi-readable error messages - at least so that you know it's a static assertion failure and not some other issue that's the problem.
I'll have another look at this when I have a chance.
static_assert seems to be one of the first C++0x features compilers are implementing. Maybe we should be working on a transition plan for BOOST_STATIC_ASSERT. Or do you already have a plan and I'm just behind the times? --Beman
Beman Dawes wrote:
John Maddock wrote:
... As you can see, it fails at line 3 as it should, while not complaining about line 2. It will not complain about any old-style-cast either. So the test was completely successful.
Hardly that successful: those error messages are awful! The whole point of BOOST_STATIC_ASSERT is to provide semi-readable error messages - at least so that you know it's a static assertion failure and not some other issue that's the problem.
I'll have another look at this when I have a chance.
static_assert seems to be one of the first C++0x features compilers are implementing. Maybe we should be working on a transition plan for BOOST_STATIC_ASSERT. Or do you already have a plan and I'm just behind the times?
There's already a hook in the implementation to the native static_assert when available, however, a new macro that accepts a message string as well as the test might well be in order :-) John.
participants (6)
-
Beman Dawes
-
Erik
-
Jean-Francois Bastien
-
Joel FALCOU
-
John Maddock
-
Ricardo Muñoz