Boost logo

Boost :

Subject: Re: [boost] [wave] preprocessor directives in output
From: Eric Niebler (eniebler_at_[hidden])
Date: 2014-01-21 20:25:07


On 01/21/2014 04:47 PM, Hartmut Kaiser wrote:
>
>> On 01/21/2014 04:20 PM, pmenso57_at_[hidden] wrote:
>>> Eric, just be very careful about what macros expand when. E.g. the
>> expression:
>>>
>>> !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
>>>
>>> will get expanded on the first preprocessor pass to something like
>>>
>>> !defined(1)
>>>
>>> (or whatever it expands to)
>>
>>
>> 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?

The code is getting expanded *in* the pragma region, but I think I can
guess what's happening. I have this:

#define FUSION_HASH #
#if defined(__WAVE__) && \
    defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
    (defined(__WAVE__) && \
     defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
        vector(vector&& rhs)
            : vec(std::forward<vector_n>(rhs.vec)) {}
// more code that uses rvalue references
#endif
#if defined(__WAVE__) && \
    defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH endif
#endif
#undef FUSION_HASH

When wave is preprocessing the files, it spits out:

# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
        vector(vector&& rhs)
            : vec(std::forward<vector_n>(rhs.vec)) {}
#endif

as it should. That's because BOOST_NO_CXX11_RVALUE_REFERENCES is not
defined, and because it doesn't get replaced with 0, which would only
happen if wave thought it was evaluating a #if ... which it's not.

This begs the question of which compiler config wave uses. Does it try
to emulate a known compiler? If so, which? And what version? It's never
occurred to me before to wonder what #defines are set when wave
processes #include <boost/config.hpp>.

Eric


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