Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2006-02-21 07:20:15


 

> -----Original Message-----
> From: boost-bounces_at_[hidden]
> [mailto:boost-bounces_at_[hidden]] On Behalf Of Serguei KOLOS
> Sent: Tuesday, February 21, 2006 12:42 AM
> To: boost_at_[hidden]
> Subject: [boost] problem with BOOST_PP_IS_EMPTY macro
>
> Hello
>
> Using the BOOST_PP_IS_EMPTY macro with string literal as
> parameter causes compiler warning:
> warning: pasting "BOOST_PP_IS_EMPTY_DEF_" and ""AA"" does not
> give a valid preprocessing token

That macro is 1) not a library interface (so why are you using it?) and 2) is
not a general purpose emptiness detector (there is no such thing). There are
very specific constraints on what the input is supposed to be.

> #include <boost/preprocessor/if.hpp>
> #include <boost/preprocessor/tuple.hpp>
> #include <boost/preprocessor/facilities/is_empty.hpp>
>
> #define MY_BOOST_PP_IS_EMPTY(x)
> MY_BOOST_PP_IS_EMPTY_I(MY_BOOST_PP_IS_EMPTY_HELPER x)

First, this will fail if 'x' is a parenthesized expression. I.e. if 'x' is ()
or (a) or (a, b), etc.. It will also fail if 'x' ends with a function-like
macro name.

Second, passing nothing--as in TEST_CASE_1( ) and TEST_CASE_2( )--is results in
undefined behavior in current C++ (which will give you warnings on many
preprocessors).

Third, even with placemarkers from C99 (well-defined semantics for empty
arguments), you still cannot generally test emptiness. Trust me, there is *no*
way to do it. The best that you can do is to contrain the input to a subset of
non-pathological input.

The macros in the library, IS_EMPTY, IS_1, and IS_EMPTY_OR_1 are all designed
for a very specific purpose: testing flags such as:

#define CONFIG_A
#define CONFIG_B 1
#define CONFIG_C 0

IS_EMPTY(CONFIG_A) // 1
IS_EMPTY(CONFIG_B) // 0
IS_EMPTY(CONFIG_C) // 0

IS_1(CONFIG_A) // 0
IS_1(CONFIG_B) // 1
IS_1(CONFIG_C) // 0

IS_EMPTY_OR_1(CONFIG_A) // 1
IS_EMPTY_OR_1(CONFIG_B) // 1
IS_EMPTY_OR_1(CONFIG_C) // 0

In other words, they are for testing simply flags. Valid input is either 0 or
1, or a macro expansion that results in 0 or 1 or nothing. Nothing else is even
supposed to work. But, as I said above, these are not library interfaces. You
can use them, but make sure that you use them correctly.

Regarding emptiness detection in general, it can't be done without well-defined
semantics for token-pasting arbitrary tokens (i.e. where the result is not a
single valid preprocessing token). With variadics and placemarkers (i.e. C99
facilities) you can get awfully close--the contraint is that you cannot have a
function-like macro name as the end of the input--but that is as close as you
can get.

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