views:

98

answers:

1

I added following at line 42 of proto.h:

typedef boost::make_unsigned<off_t>::type uoff_t;

And now I get this verbose and confusing warning from gcc complaining about comparing an enum to the same enum type:

In file included from proto.cpp:12:
/usr/local/include/boost/type_traits/is_unsigned.hpp: In instantiation of 'boost::detail::is_ununsigned_helper<long int>':
/usr/local/include/boost/type_traits/is_unsigned.hpp:73:   instantiated from 'boost::detail::is_unsigned_imp<long int>'
/usr/local/include/boost/type_traits/is_unsigned.hpp:123:   instantiated from 'boost::is_unsigned<long int>'
/usr/local/include/boost/type_traits/make_unsigned.hpp:110:   instantiated from 'boost::detail::make_unsigned_imp<long int>'
/usr/local/include/boost/type_traits/make_unsigned.hpp:130:   instantiated from 'boost::make_unsigned<long int>'
proto.h:42:   instantiated from here
/usr/local/include/boost/type_traits/is_unsigned.hpp:40: warning: comparison between 'enum boost::detail::is_unsigned_values<long int>::<anonymous>' and 'enum boost::detail::is_unsigned_values<long int>::<anonymous>'

Can anyone decipher this?

+3  A: 

This is what happens

BOOST_NO_INCLASS_MEMBER_INITIALIZATION gets defined in Boost.Config (not sure why it would for gcc, but I'll leave that alone for the moment). Thus,

BOOST_STATIC_CONSTANT(no_cv_t, minus_one = (static_cast<no_cv_t>(-1)));
BOOST_STATIC_CONSTANT(no_cv_t, zero = (static_cast<no_cv_t>(0)));

declarations in boost::detail::is_unsigned_values get expanded to

enum { minus_one = (static_cast<no_cv_t>(-1)) };
enum { zero = (static_cast<no_cv_t>(0)) };

then these two enumerators of unnamed but different enumerations get compared in boost::detail::is_ununsigned_helper. Hence the warning, which wouldn't have happened if BOOST_STATIC_CONSTANT() were expanded to static const no_cv_t blah blah....

There are two questions left to be answered:

-> Why does BOOST_NO_INCLASS_MEMBER_INITIALIZATION get defined in your case?

-> If that macro does get defined, such a warning (comparison of enumerators of different enums) can be produced. It's harmless here, yet it might be nice to be prevented in Boost. Is that worth it?

Note: I used Boost 1.43's code for reference.

usta