Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2004-03-04 19:03:37


> -----Original Message-----
> From: boost-bounces_at_[hidden]
> [mailto:boost-bounces_at_[hidden]] On Behalf Of Jonathan Turkanis

> When I compile the following simple program on VC6:
>
> #include <boost/preprocessor/facilities/empty.hpp>
> #include <boost/preprocessor/punctuation/comma_if.hpp>
>
> #define PARAM(has_param) BOOST_PP_IF(has_param, typename Param,
> BOOST_PP_EMPTY())
> #define MACRO(has_param)
> \
> template< PARAM(has_param)
> BOOST_PP_COMMA_IF(has_param) typename T> \
> struct name { };
> \
> /**/
>
> MACRO(0)
>
> int main() { return 0; }
>
> I get the following warnings:
>
> warning C4003: not enough actual parameters for macro
> 'BOOST_PP_IIF'
> warning C4003: not enough actual parameters for macro
> 'BOOST_PP_IIF_I'
> warning C4003: not enough actual parameters for macro
> 'BOOST_PP_IIF_0'

VC is correct. You are passing nothing as an argument to a macro that is
invoked internally:

#define IIF(bit, t, f) PRIMITIVE_CAT(IIF_, bit)(t, f)
#define IIF_0(t, f) f
#define IIF_1(t, f) t

#define IF(cond, t, f) IIF(BOOL(cond), t, f)

When you pass EMPTY() as an argument to IF, it expands to nothing before the
replacement list is rescanned, yielding:

IIF(BOOL(cond), t, )

Which is not currently defined in C++.

> It works fine on other compilers.

However, it is well-defined in C99, and many other compilers (such as GCC, EDG,
Metrowerks) support C99 features.

> Am I missusing the preprocessor library, or is this a problem
> with VC6? If the latter, is there a workaround, or should I
> just turn off warning 4003?

The workaround is to do with with well-defined semantics, or use a different
construct:

> #include <boost/preprocessor/facilities/empty.hpp>
> #include <boost/preprocessor/punctuation/comma_if.hpp>
>
> #define PARAM(has_param) BOOST_PP_IF(has_param, typename Param,
> BOOST_PP_EMPTY())
> #define MACRO(has_param)

#include <boost/preprocessor/control/expr_if.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/facilities/comma_if.hpp>
#include <boost/preprocessor/facilities/identity.hpp>

#define PARAM(has_param) \
    BOOST_PP_IF( \
        BOOST_PP_IDENTITY(typename Param), \
        BOOST_PP_EMPTY \
    )() \
    /**/

// or:
// #define PARAM(has_param) \
// BOOST_PP_EXPR_IF(has_param, typename Param) \
// /**/

#define MACRO(has_param) \
    template< \
        PARAM(has_param) BOOST_PP_COMMA_IF(has_param) \
        typename T> \
    struct name { }; \
    /**/

MACRO(0)

int main() { return 0; }

Regards,
Paul Mensonides


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