
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Tobias Schwinger
[...] which creates pathological input that IF cannot deal with: [...]
While we're at it:
This code (taken from boost/typeof/vector.hpp, line 106)
BOOST_PP_IF(n, BOOST_PP_EMPTY(), class T = void)
seems to contain a similar (but more subtle) problem.
Emptiness (well, deferred emptiness in this case, to be precise) is passed to BOOST_PP_IF as the second argument, and empty input (to the macros used by BOOST_PP_IF internally) results in undefined behaviour -- so it's up to the preprocessor whether things work correctly or not.
This is exactly right. In current C++, empty arguments amount to undefined behavior. Many preprocessors allow it, and C99 requires it to work, but it *shouldn't* work in current C++.
For a quick fix, a more bullet-proof version could look like this
BOOST_PP_IF(n,BOOST_PP_EMPTY,BOOST_PP_IDENTITY(class T = void))()
or
BOOST_PP_EXPR_IIF(BOOST_PP_NOT(n), class T = void)
The latter of the two is the better solution, IMO. You could also do: BOOST_PP_IF( n, BOOST_PP_TUPLE_EAT, BOOST_PP_TUPLE_REM )(1)(class T = void) This allows the 'class T = void' part to be a macro invocation that is lazily evaluated (or at least, is _supposed_ to be lazily evaluated). E.g. BOOST_PP_IF( n, BOOST_PP_TUPLE_EAT, BOOST_PP_TUPLE_REM )(1)( EXPENSIVE_MACRO_INVOCATION() ) ...where EXPENSIVE_MACRO_INVOCATION() is only invoked if 'n' is 0. Regards, Paul Mensonides