Boost logo

Boost :

Subject: Re: [boost] [Math.Constants] Help needed with the preprocessor
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2011-12-16 15:26:44


On Fri, Dec 16, 2011 at 10:23 AM, John Maddock <boost.regex_at_[hidden]>wrote:

> Folks we have a problem: rather late in the day I've discovered that our
> Math.Constants code doesn't compile on anything except VC++, and the
> problem is preprocessor token pasting. So I'm hoping we have some experts
> around here that can help!
>
> The issue is we currently construct the constants from a macro invocation
> such as:
>
> BOOST_DEFINE_MATH_CONSTANT(**half, 5.**000000000000000000000000000000**000000,
> 000000000000000000000000000000**000000000000000000000000000000**00000000000000,
> -01);
>
> But the "-01" part (the exponent) isn't a valid pp-token, so trying to
> token-paste it fails on GCC (compiler error).
>
> Does anyone know if there's a way to overcome this?
>

Maybe include the "e" in that 4th argument? E.g., "e-01". If you actually
need to recover the "-01" without the e, I'm pretty sure you can do
something like

#define remove_e( X ) BOOST_PP_CAT( remove_e_, X )
#define remove_e_e
#define remove_e_E // prefer "E" instead?

Weak explanation for why I believe this will work below...

As an alternative, I've considered something like:
>
> BOOST_DEFINE_MATH_CONSTANT(ln_**two, 6.**931471805599453094172321214581**765680e-001,
> "6.**931471805599453094172321214581**765680755001343602552541206800**
> 094933936219696947156058633269**96418687542001481021e-001");
>
> But this would still require token pasting of the
>
> 6.**931471805599453094172321214581**765680e-001
>
> part. But is this now a valid pp-token if the "-" is internal to the
> token? It works on the compilers I've tried, but I don't want to be
> skewered by this again down the line....
>
> Truly hating the preprocessor yours, John.

>From my experience, only the characters on which the preprocessor is
slabbing glue for the token pasting matters, and anything you can use in a
C++ identifier is fine there. I know Lorenzo's done some crazy stuff with
token pasting with things that looks like "const bind & identifier", e.g.,
detecting the presence of the "const" and "bind" keywords, and I presume
the internal "&" doesn't mess things up.

I'm not an expert in the technicalities of the preprocessor, however.

- Jeff


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk