Boost logo

Boost :

Subject: [boost] gcc4.3 warning for multiple scope_exits
From: Kim Barrett (kab.conundrums_at_[hidden])
Date: 2009-07-09 14:00:20


Boost.ScopeExit uses a tricky bit of code (from Steven Watanabe) to allow a
macro expansion to contain code which will declare a variable exactly once,
regardless of how many times the macro is used in a given
scope. Unfortunately, gcc4.3 -Wall generates a warning for this code in the
second and later uses of the macro in the same scope. The warning is

   comparisons like X<=Y<=Z do not have their mathematical meaning

It is complaining about a statement that gets parsed as

   identifier < 0 > variable;

Valid code, and correct in this particular case, but the warning is there
never the less.

I realize that boost doesn't have a no-warnings policy (dealing with compiler
variations that lead to actual errors is hard enough), but since my team has a
general policy of using -Werror and I've been proselytizing the use of
scope_exit within our group, I was motivated to find a way to kill this
warning.

After studying Steven's trick (ouch! my brain hurts) I've come up with an
extension of the same technique which avoids the warning, using the time
honored approach of adding another level of indirection. Here's my patch:

----------

--- scope_exit.hpp.orig 2009-07-09 13:19:36.000000000 -0400
+++ scope_exit.hpp.new 2009-07-09 13:20:04.000000000 -0400
@@ -36,14 +36,21 @@
      typedef void* declared;
      struct undeclared { declared dummy[2]; };

+ template<int>
+ struct holder
+ {
+ declared value;
+ static const int apply_value = 0;
+ friend void operator>(int, const holder&) {}
+ };
+
      template<>
      struct declare<sizeof(undeclared)>
      {
          template<int>
          struct apply
          {
- declared value;
- friend void operator>(bool, const apply&) {}
+ static const int apply_value = 0;
          };
      };

@@ -214,8 +221,9 @@
          BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_MEMBER, id,
seq) \
          BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, seq)
\
      } BOOST_SCOPE_EXIT_AUX_PARAMS(id)
BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id, seq)\
- boost::scope_exit::aux::declare<sizeof(boost_scope_exit_args)>
\
- ::apply<0> boost_scope_exit_args;
\
+ boost::scope_exit::aux::holder<
\
+
boost::scope_exit::aux::declare<sizeof(boost_scope_exit_args)>
\
+ ::apply<0>::apply_value> boost_scope_exit_args;
\
      boost_scope_exit_args.value = &BOOST_SCOPE_EXIT_AUX_PARAMS(id);
\
      struct BOOST_SCOPE_EXIT_AUX_GUARD_T(id) {
\
          BOOST_SCOPE_EXIT_AUX_PARAMS_T(id)* boost_se_params_;
\


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk