Preprocessor warning from BOOST_PP_SEQ_ELEM

Hi All, When I run the following code through the preprocessor, it emits the correct output: alpha is simple; beta is simple; gamma is complex and color is red; delta is simple; epsilon is complex ; but it also emits the folowing warning (several times): macro "BOOST_PP_SEQ_ELEM_III" requires 2 arguments, but only 1 given My question is, how can I eliminate the warning. Thanks in advance for any comments/advice. # include <boost/preprocessor/library.hpp> #define IS_SIMPLE(t) BOOST_PP_NOT_EQUAL(3, BOOST_PP_SEQ_SIZE(t)) #define PROPERTIES(t) BOOST_PP_SEQ_ELEM(2,t) #define HAS_COLOR(t) BOOST_PP_EQUAL(2, BOOST_PP_SEQ_ELEM(0, \ PROPERTIES(t))) #define COLOR(t) BOOST_PP_SEQ_ELEM(1, PROPERTIES(t)) #define FSIMPLE(a, s, i, t) \ BOOST_PP_SEQ_ELEM(0,t) is simple; #define FCOMPLEX(a, s, i, t) \ BOOST_PP_SEQ_ELEM(0,t) is complex \ BOOST_PP_IF(HAS_COLOR(t), and color is COLOR(t) , ); #define FCHOICE(a, s, i, t) \ BOOST_PP_IF(IS_SIMPLE(t), \ FSIMPLE(a, s, i, t), \ FCOMPLEX(a, s, i, t)) #define T(s)\ BOOST_PP_SEQ_FOR_EACH_I(FCHOICE, s, s) \ T ( // ID Frequency Properties ( (alpha) (16) ) ( (beta) (3) ) ( (gamma) (13) ((2) (red)) ) ( (delta) (5) ) ( (epsilon) (13) ((4) (heavy)) ) )

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Edward Bishop
My question is, how can I eliminate the warning. Thanks in advance for any comments/advice.
# include <boost/preprocessor/library.hpp>
#define IS_SIMPLE(t) BOOST_PP_NOT_EQUAL(3, BOOST_PP_SEQ_SIZE(t)) #define PROPERTIES(t) BOOST_PP_SEQ_ELEM(2,t) #define HAS_COLOR(t) BOOST_PP_EQUAL(2, BOOST_PP_SEQ_ELEM(0, \ PROPERTIES(t))) #define COLOR(t) BOOST_PP_SEQ_ELEM(1, PROPERTIES(t))
#define FSIMPLE(a, s, i, t) \ BOOST_PP_SEQ_ELEM(0,t) is simple;
#define FCOMPLEX(a, s, i, t) \ BOOST_PP_SEQ_ELEM(0,t) is complex \ BOOST_PP_IF(HAS_COLOR(t), and color is COLOR(t) , ); ^^^ This is undefined behavior in C++. Should be:
#define FCOMPLEX(a, s, i, t) \ BOOST_PP_SEQ_ELEM(0,t) is complex \ BOOST_PP_EXPR_IF(HAS_COLOR(t), and color is COLOR(t)); \
#define FCHOICE(a, s, i, t) \ BOOST_PP_IF(IS_SIMPLE(t), \ FSIMPLE(a, s, i, t), \ FCOMPLEX(a, s, i, t))
The IF here is not lazy. Both the true and false cases are being evaluated, but then one is discarded. Should be: #define FCHOICE(a, s, i, t) \ BOOST_PP_IF(IS_SIMPLE(t), FSIMPLE, FCOMPLEX)(a, s, i, t) Regards, Paul Mensonides

Paul Mensonides wrote:
BOOST_PP_IF(HAS_COLOR(t), and color is COLOR(t) , );
^^^ This is undefined behavior in C++. Should be:
May a PP-Sequence have '()'-elements ? The documentation says that "a sequence cannot be empty" which seems to be something different than containing empty elements...

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Tobias Schwinger Sent: Wednesday, March 02, 2005 9:21 AM To: boost@lists.boost.org Subject: [boost] Empty sequence elements
Paul Mensonides wrote:
BOOST_PP_IF(HAS_COLOR(t), and color is COLOR(t) , );
^^^ This is undefined behavior in C++. Should be:
May a PP-Sequence have '()'-elements ?
Not until C++ gets placemarkers (i.e. empty arguments) from C99. Without them, "emptiness" is not an element. '()' is just nullary parentheses. Without variadics, a mechanism can only handle sequences in which each element is a specific arity. In the pp-lib, they must be unary (i.e. not nullary). It is certainly possible (in current C++) to define primitives for (e.g.) a binary sequence, but I'd have to replicate the entire mechanism. Even if binary sequence primitives where there, you still couldn't have (,) or (a,) or (,b) because each "element" would be a comma-separated pair of elements, and emptiness is not an element.
The documentation says that "a sequence cannot be empty" which seems to be something different than containing empty elements...
Yes, when the documentation says the above it means there is no such thing as a nil sequence. E.g. (a)(b)(c) // 3-element, unary sequence (a)(b) // 2-element, unary sequence (a) // 1-element, unary sequence // 0-element sequence, n-ary sequence The 0-element sequence has a representation (emptiness), but that representation is not yet valid C++. In other words, the reason that you can't have empty sequences and can't have empty elements is the same reason. This applies generally: you can't have empty arguments, you can't have empty tuple elements, you can't have empty list elements, etc.. With placemarkers, that will change, because placemarkers are a well-defined way of saying that an entity can be nothing. Until that happens, it is undefined behavior. :( Regards, Paul Mensonides

Paul Mensonides wrote:
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Tobias Schwinger Sent: Wednesday, March 02, 2005 9:21 AM To: boost@lists.boost.org Subject: [boost] Empty sequence elements
Paul Mensonides wrote:
BOOST_PP_IF(HAS_COLOR(t), and color is COLOR(t) , );
^^^ This is undefined behavior in C++. Should be:
May a PP-Sequence have '()'-elements ?
Not until C++ gets placemarkers (i.e. empty arguments) from C99. Without them, "emptiness" is not an element. '()' is just nullary parentheses. Without variadics, a mechanism can only handle sequences in which each element is a specific arity. In the pp-lib, they must be unary (i.e. not nullary). It is certainly possible (in current C++) to define primitives for (e.g.) a binary sequence, but I'd have to replicate the entire mechanism. Even if binary sequence primitives where there, you still couldn't have (,) or (a,) or (,b) because each "element" would be a comma-separated pair of elements, and emptiness is not an element.
The documentation says that "a sequence cannot be empty" which seems to be something different than containing empty elements...
Yes, when the documentation says the above it means there is no such thing as a nil sequence. E.g.
(a)(b)(c) // 3-element, unary sequence (a)(b) // 2-element, unary sequence (a) // 1-element, unary sequence // 0-element sequence, n-ary sequence
The 0-element sequence has a representation (emptiness), but that representation is not yet valid C++. In other words, the reason that you can't have empty sequences and can't have empty elements is the same reason. This applies generally: you can't have empty arguments, you can't have empty tuple elements, you can't have empty list elements, etc.. With placemarkers, that will change, because placemarkers are a well-defined way of saying that an entity can be nothing. Until that happens, it is undefined behavior. :(
Thank you for this very detailed reply ! Is it safe to use BOOST_PP_EMTPY or BOOST_PP_INDENTITY(somthing) as the element and "dereference" with '()' ?

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Tobias Schwinger
Thank you for this very detailed reply !
Is it safe to use BOOST_PP_EMTPY or BOOST_PP_INDENTITY(somthing) as the element and "dereference" with '()' ?
Sure, provided that the result is never "bound" to an argument by itself. E.g. #define A(x) B(x) #define B(x) x A() // undefined: empty argument to A A( BOOST_PP_EMPTY() ) // undefined: empty argument to B A( BOOST_PP_EMPTY )() // okay Regards, Paul Mensonides

Paul Mensonides wrote:
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Tobias Schwinger
Thank you for this very detailed reply !
Is it safe to use BOOST_PP_EMTPY or BOOST_PP_INDENTITY(somthing) as the element and "dereference" with '()' ?
Sure, provided that the result is never "bound" to an argument by itself. E.g.
#define A(x) B(x) #define B(x) x
A() // undefined: empty argument to A
A( BOOST_PP_EMPTY() ) // undefined: empty argument to B
A( BOOST_PP_EMPTY )() // okay ^^^
This is about what I meant (well, BOOST_PP_SEQ_ELEM(x,s)() - x being the index of the "optional element" in a sequence). But according to the source of SEQ_ELEM this should work as well. Thanx, again. Regards, Tobias
participants (3)
-
Edward Bishop
-
Paul Mensonides
-
Tobias Schwinger