$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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