Boost logo

Boost :

From: Hartmut Kaiser (hartmut.kaiser_at_[hidden])
Date: 2008-07-12 12:53:47


> A recent change to the development version of the gcc preprocessor
> changes the way it processes '#elif' directives and breaks a common
> use of the preprocessor library. We've already had reports of this
> causing problems in MPL, and it might also affect: variant,
> function_types, python, fusion, xpressive and phoenix. Details of the
> change are at:
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36320
>
> With this change, the argument to an '#elif' directive is processed
> even if a previous '#if'/'#elif' directive was true. This causes the
> example use of BOOST_PP_ITERATION_DEPTH to break:
>
> http://www.boost.org/doc/libs/1_35_0/libs/preprocessor/doc/ref/iteratio
> n_depth.html
>
> In this example, the first time the header is included,
> BOOST_PP_ITERATION_DEPTH is not yet defined, so it causes the
> develoment gcc to fail when the #elif directives are evaluated (which
> are skipped with existing versions, because the first #if directive
> evaluates to true).
>
> Looking at the standard, I think their interpretation is correct
> (although I'm not familiar with it and could be missing something) but
> it isn't clear that this was the intent of the authors. Any opinions
> on this?
>
> I think it's quite easy to work around, we can replace:
>
> #if !BOOST_PP_IS_ITERATING
> // ....
> #elif BOOST_PP_ITERATION_DEPTH() == 1
> // ....
> #elif BOOST_PP_ITERATION_DEPTH() == 2
> // ....
> #endif
>
> with:
>
> #if !BOOST_PP_IS_ITERATING
> // ....
> #else
> # if BOOST_PP_ITERATION_DEPTH() == 1
> // ....
> # elif BOOST_PP_ITERATION_DEPTH() == 2
> // ....
> # endif
> #endif
>
> So that the calls to BOOST_PP_ITERATION_DEPTH are skipped - or we
> could just include the necessary header before including the file. But
> it does seem a pity that any code which uses this technique might need
> to be changed for gcc 4.4. We should probably write to them about this
> (it doesn't look like they realised this would be a problem), but I'm
> writing here first in case anyone has any ideas.

Hmm, seems they flushed out the baby with the bath (as we say in Germany).
Adding a diagnostic message if the expression in #elif is empty is a valid
concern, but requiring this expression to be fully defined and meaningful is
just nonsense, IMHO.

FWIW, Wave makes sure the expression is not empty, but skips evaluating it
if a previous #if/#elif was true.

Regards Hartmut


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