
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] 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