
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' It works fine on other compilers. 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? Jonathan

"Jonathan Turkanis" <technews@kangaroologic.com> wrote in message news:c289qo$bag$1@sea.gmane.org...
When I compile the following simple program on VC6:
Here's a more nicely formatted version (I hope): #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; }

Jonathan Turkanis wrote:
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'
It works fine on other compilers.
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?
BOOST_PP_EMPTY() evaluates to nothing, so I would think that VC6 is actually right. I'm probably wrong though, I'm no PP guru. ;) Anyway, I think you should do: #define PARAM(has_param) BOOST_PP_IF( \ has_param \ , BOOST_PP_IDENTITY(typename Param) \ , BOOST_PP_EMPTY)() HTH, -- Daniel Wallin

"Daniel Wallin" <dalwan01@student.umu.se> wrote in message news:4047B47D.9010304@student.umu.se...
Jonathan Turkanis wrote:
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'
<snip>
BOOST_PP_EMPTY() evaluates to nothing, so I would think that VC6 is actually right. I'm probably wrong though, I'm no PP guru. ;) Anyway, I think you should do:
#define PARAM(has_param) BOOST_PP_IF( \ has_param \ , BOOST_PP_IDENTITY(typename Param) \ , BOOST_PP_EMPTY)()
Yes, that's better. It's hard to believe that VC6 could be the only conforming preprocessor on this point. though ;-) Thanks. Jonathan

[mailto:boost-bounces@lists.boost.org] On Behalf Of Jonathan Turkanis
#define PARAM(has_param) BOOST_PP_IF( \ has_param \ , BOOST_PP_IDENTITY(typename Param) \ , BOOST_PP_EMPTY)()
Yes, that's better. It's hard to believe that VC6 could be the only conforming preprocessor on this point. though ;-)
It isn't that other compilers are non-conforming, they just chose a different way to handle undefined behavior. C++ will likely soon have the new facilities of C99's preprocessor, which will include variadic macros and placemarkers (which would allow your original code). So, other preprocessors are just using forward-thinking to handle the undefined behavior, while VC's preprocessor (all the way through VC71) is just a complete relic. Regards, Paul Mensonides

"Paul Mensonides" <pmenso57@comcast.net> wrote in message news:002d01c40245$b0e71630$6401a8c0@c161550b...
[mailto:boost-bounces@lists.boost.org] On Behalf Of Jonathan Turkanis
#define PARAM(has_param) BOOST_PP_IF( \ has_param \ , BOOST_PP_IDENTITY(typename Param) \ , BOOST_PP_EMPTY)()
Yes, that's better. It's hard to believe that VC6 could be the only conforming preprocessor on this point. though ;-)
It isn't that other compilers are non-conforming, they just chose a different way to handle undefined behavior. C++ will likely soon have the new facilities
forward-thinking to handle the undefined behavior, while VC's
Yeah, I realized this after I sent it. preprocessor (all
the way through VC71) is just a complete relic.
Is it really the same preprocessor? Jonathan

[mailto:boost-bounces@lists.boost.org] On Behalf Of Jonathan Turkanis
forward-thinking to handle the undefined behavior, while VC's preprocessor (all the way through VC71) is just a complete relic.
Is it really the same preprocessor?
There are slight changes, but otherwise it is the same horrid old VC6 preprocessor. Regards, Paul Mensonides

-----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

"Paul Mensonides" <pmenso57@comcast.net> wrote in message news:002c01c40245$4f522900$6401a8c0@c161550b...
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Jonathan Turkanis
When you pass EMPTY() as an argument to IF, it expands to nothing before the replacement list is rescanned, yielding:
Somehow I thought EMPTY() would be lazier. I guess it can't be that smart -- it wouldn't know how lazy to be.
#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 { }; \ /**/
I like the first better because it's self-contained. Thanks for your patience with my preprocessor naïveté. Jonathan

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Jonathan Turkanis
When you pass EMPTY() as an argument to IF, it expands to nothing before the replacement list is rescanned, yielding:
Somehow I thought EMPTY() would be lazier. I guess it can't be that smart -- it wouldn't know how lazy to be.
You'd be surprised. :) Chaos can do things very similar to this. #include <chaos/preprocessor/punctuation/comma.h> #include <chaos/preprocessor/recursion/expr.h> #include <chaos/preprocessor/recursion/rail.h> #define RCOMMA() CHAOS_PP_RAIL(CHAOS_PP_COMMA)() #define A(x) B(x) #define B(x) C(x) #define C(x) D(x) #define D(x) x A(CHAOS_PP_COMMA()) // error CHAOS_PP_EXPR(CHAOS_PP_WALL( A(RCOMMA()) ) // , Further, Chaos can count the number of scans that the argument x undergoes, and then delay an invocation until just before the last scan: #include <chaos/preprocessor/arithmetic/dec.h> #include <chaos/preprocessor/recursion/delay.h> #include <chaos/preprocessor/recursion/delve.h> #define AF CHAOS_PP_HALT( A(CHAOS_PP_DELVE()) ) A( CHAOS_PP_DELAY(CHAOS_PP_DEC(AF), CHAOS_PP_COMMA)() ) // , Of course, this is all irrelevant in this case anyway because IF is already lazy in Chaos: #include <chaos/preprocessor/facilities/empty.h> #include <chaos/preprocessor/control/if.h> #define PARAM(has_param) \ CHAOS_PP_IF(has_param)( \ typename Param, CHAOS_PP_EMPTY() \ ) \ /**/
#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) \ // /**/
I like the first better because it's self-contained.
I prefer the second in most cases because it requires the use of less primitives.
Thanks for your patience with my preprocessor naïveté.
No problem at all. Regards, Paul Mensonides
participants (3)
-
Daniel Wallin
-
Jonathan Turkanis
-
Paul Mensonides