[Boost-users] Ugly warnings from BOOST_STATIC_ASSERT

60 views
Skip to first unread message

Erik

unread,
Mar 17, 2008, 2:02:17 PM3/17/08
to boost...@lists.boost.org
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

Is there any chance to get this fixed?
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

John Maddock

unread,
Mar 18, 2008, 5:43:08 AM3/18/08
to boost...@lists.boost.org
Erik 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
>
> Is there any chance to get this fixed?

Which compiler is this?

Thanks, John.

Erik

unread,
Mar 18, 2008, 6:17:10 AM3/18/08
to boost...@lists.boost.org
John Maddock skrev:

> Erik 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
>>
>> Is there any chance to get this fixed?
>>
>
> Which compiler is this?
>
g++ (with the parameter -Wold-style-cast)

Nat Goodspeed

unread,
Mar 18, 2008, 10:34:49 AM3/18/08
to boost...@lists.boost.org
Erik wrote:
> John Maddock skrev:
>> Erik 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
>>>
>> Which compiler is this?
>>
> g++ (with the parameter -Wold-style-cast)

I bet he's going to ask you which version of g++ you're using. Behavior
can vary widely across versions.

Erik

unread,
Mar 18, 2008, 11:05:09 AM3/18/08
to boost...@lists.boost.org
Nat Goodspeed skrev:

> Erik wrote:
>
>> John Maddock skrev:
>>
>>> Erik 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
>>>>
>>>>
>>> Which compiler is this?
>>>
>>>
>> g++ (with the parameter -Wold-style-cast)
>>
>
> I bet he's going to ask you which version of g++ you're using. Behavior
> can vary widely across versions.

I do not think so. An old-style-cast is a well-defined thing and all
versions of g++ that has -Wold-style-cast should catch them. The only
thing that varies between versions is that g++-4.2 and later also have
-Werror=old-style-cast.

Note: This is what the creator of C++ has to say about old-style-cast:
«From C, C++ inherited the notation (T) e, which performs any conversion
that can be expressed as a combination of static_casts,
reinterpret_casts, and const_casts to make a value of type T from the
expression e (§B.2.3). This C-style cast is far more dangerous than the
named conversion operators because the notation is harder to spot in a
large program and the kind of conversion intended by the programmer is
not explicit. That is, (T) e might be doing a portable conversion
between related types, a nonportable conversion between unrelated types,
or removing the const modifier from a pointer type. Without knowing the
exact types of T and e, you cannot tell.» (Stroustrup, 2000)

Jean-Francois Bastien

unread,
Mar 18, 2008, 12:12:10 PM3/18/08
to boost...@lists.boost.org
> 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

Erik

unread,
Mar 18, 2008, 1:31:40 PM3/18/08
to boost...@lists.boost.org
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).

John Maddock

unread,
Mar 18, 2008, 1:31:55 PM3/18/08
to boost...@lists.boost.org
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

static_assert.hpp

Ricardo Muñoz

unread,
Mar 18, 2008, 4:19:49 PM3/18/08
to boost...@lists.boost.org

Hi!, hope this help:

ricardo@miles:~/devel$ cat foo_static.cpp
#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT(sizeof(int) >= sizeof(short));

int main()
{
return 0;
}
ricardo@miles:~/devel$ svn info boost-trunk/
Path: boost-trunk
URL: http://svn.boost.org/svn/boost/trunk
Repository Root: http://svn.boost.org/svn/boost
Repository UUID: b8fc166d-592f-0410-95f2-cb63ce0dd405
Revision: 43710
Node Kind: directory
Schedule: normal
Last Changed Author: bemandawes
Last Changed Rev: 43709
Last Changed Date: 2008-03-18 20:35:18 +0100 (Tue, 18 Mar 2008)

ricardo@miles:~/devel$ gcc --version
gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ricardo@miles:~/devel$ gcc foo_static.cpp -o foo_static -Wall
-Wold-style-cast -I./boost-trunk/
ricardo@miles:~/devel$

Regards,

> _______________________________________________
> Boost-users mailing list
> Boost...@lists.boost.org
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>

--
Ricardo Muñoz
Warp Networks S.L. http://www.warp.es

Erik

unread,
Mar 18, 2008, 6:28:00 PM3/18/08
to boost...@lists.boost.org
John Maddock skrev:

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.

John Maddock

unread,
Mar 19, 2008, 5:35:09 AM3/19/08
to boost...@lists.boost.org

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

unread,
Mar 19, 2008, 5:56:10 AM3/19/08
to boost...@lists.boost.org
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...

Erik

unread,
Mar 19, 2008, 6:02:15 AM3/19/08
to boost...@lists.boost.org
John Maddock skrev:

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

Erik

unread,
Mar 19, 2008, 6:33:10 AM3/19/08
to boost...@lists.boost.org
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

John Maddock

unread,
Mar 19, 2008, 1:09:14 PM3/19/08
to boost...@lists.boost.org
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.

static_assert.hpp

Joel FALCOU

unread,
Mar 19, 2008, 6:49:42 PM3/19/08
to boost...@lists.boost.org
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

Erik

unread,
Mar 24, 2008, 6:04:15 PM3/24/08
to boost...@lists.boost.org
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>'

Beman Dawes

unread,
Mar 26, 2008, 4:53:44 PM3/26/08
to boost...@lists.boost.org
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

John Maddock

unread,
Mar 27, 2008, 5:31:33 AM3/27/08
to boost...@lists.boost.org
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.

Reply all
Reply to author
Forward
0 new messages