Boost logo

Boost :

Subject: Re: [boost] [wave] preprocessor directives in output
From: pmenso57_at_[hidden]
Date: 2014-01-21 20:05:45


> > Thanks for the warning, and that makes sense, but it's not what I'm
> > seeing. I'm seeing wave spit out:
> >
> > # if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
> >
> > instead of:
> >
> > # if !defined(1)
> >
> > Why would that be? Regardless, I can turn off expansion of this
> > macro
> > during preprocessing with wave's -N switch, so there's a fix should
> > I ever
> > need it.
>
> Turning off the expansion of macros used in #if conditions can cause
> all
> kind of trouble. All depends on what is inside the wave pragmas:
>
> // this stuff will be seen by wave but not generated
>
> #pragma wave option(output:file)
> // this stuff will be preprocessed and written to 'file'
> #pragma wave option(output:null)
>
> // this stuff will be seen by wave but not generated
>
>
> So if it gets expanded outside of the pragma region all is fine. Did I
> misunderstand something?

In the first pass, there is no directive. It's only purpose is to pregenerate headers. So first pass emit has to emit conditional compilation directives so that when the user includes the (pregenerated) headers, the code is subject to the user's configuration and compilation environment. That means, that first pass of the preprocessor, i.e. wave, needs to emit

  #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)

as an example.

The only way to do that is to emit a hash (#) via macro and stop the expansion of BOOST_NO_CXX11_RVALUE_REFERENCES during the first pass--either via command line option or via not including headers that define it during the first pass.

This BTW, is one of the reasons why "is defined" flags are evil. It would be better if it was

  #if !BOOST_NO_CXX11_RVALUE_REFERENCES

because in that case, you could avoid construction of the object-like name with deferral.

#define HASH #
HASH include "cat.hpp"
HASH if !CAT EMPTY (BOOST_NO_CXX, 11_RVALUE_REFERENCES)
// ...
HASH endif
#undef HASH #

first pass emits

# include "cat.hpp"
# if !CAT (BOOST_NO_CXX, 11_RVALUE_REFERENCES)
// ...
# endif

which would work correctly and is far less brittle than the use of "defined" or #ifdef/#ifndef. And yes, splitting the pp-token at that spot was intentional, since the pp-token 11_RVALUE_REFERENCES cannot be defined as a macro by a third-party.

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