[wave] preprocessor directives in output
I'm looking at automating the regeneration of Fusion's preprocess
headers with the wave tool. Currently, it's impossible because of stuff
like this (from container\vector\vector.hpp):
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
vector(vector&& rhs)
: vec(std::forward
On 1/21/14, 9:46 AM, Eric Niebler wrote:
I'm looking at automating the regeneration of Fusion's preprocess headers with the wave tool. Currently, it's impossible because of stuff like this (from container\vector\vector.hpp):
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) vector(vector&& rhs) : vec(std::forward
(rhs.vec)) {} #endif When the wave driver is run, either BOOST_NO_CXX11_RVALUE_REFERENCES is defined, in which case the block of code gets left out, or else it isn't, in which case the block of code is left in. Both are wrong. What should happen is that the #if and #else directives should be present in wave's output.
I can keep wave from expanding certain named macros with the -N switch, but there doesn't seem to be a way to selectively keep wave from evaluating #if/#else directives. Or is there?
I asked Hartmut this same question before. IIRC, it's an issue that has no workaround (or fix) yet. I hope I am wrong. Regards, -- Joel de Guzman http://www.ciere.com http://boost-spirit.com http://www.cycfi.com/
How about making macros for #if, #else, #endif BOOST_KEEP_UNTIL_WAVE_OUTPUT(if) -> #if Then tell Wave not to translate it and translate it in the output. John ________________________________________ From: Boost [boost-bounces@lists.boost.org] on behalf of Joel de Guzman [djowel@gmail.com] Sent: 21 January 2014 06:29 To: boost@lists.boost.org Subject: Re: [boost] [wave] preprocessor directives in output On 1/21/14, 9:46 AM, Eric Niebler wrote:
I'm looking at automating the regeneration of Fusion's preprocess headers with the wave tool. Currently, it's impossible because of stuff like this (from container\vector\vector.hpp):
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) vector(vector&& rhs) : vec(std::forward
(rhs.vec)) {} #endif When the wave driver is run, either BOOST_NO_CXX11_RVALUE_REFERENCES is defined, in which case the block of code gets left out, or else it isn't, in which case the block of code is left in. Both are wrong. What should happen is that the #if and #else directives should be present in wave's output.
I can keep wave from expanding certain named macros with the -N switch, but there doesn't seem to be a way to selectively keep wave from evaluating #if/#else directives. Or is there?
I asked Hartmut this same question before. IIRC, it's an issue that has no workaround (or fix) yet. I hope I am wrong. Regards, -- Joel de Guzman http://www.ciere.com http://boost-spirit.com http://www.cycfi.com/ _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 01/21/2014 08:17 AM, Fletcher, John P wrote:
How about making macros for #if, #else, #endif
BOOST_KEEP_UNTIL_WAVE_OUTPUT(if) -> #if
Then tell Wave not to translate it and translate it in the output.
the problem is that pp macros can't be expanded to pp directives.
John ________________________________________ From: Boost [boost-bounces@lists.boost.org] on behalf of Joel de Guzman [djowel@gmail.com] Sent: 21 January 2014 06:29 To: boost@lists.boost.org Subject: Re: [boost] [wave] preprocessor directives in output
On 1/21/14, 9:46 AM, Eric Niebler wrote:
I'm looking at automating the regeneration of Fusion's preprocess headers with the wave tool. Currently, it's impossible because of stuff like this (from container\vector\vector.hpp):
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) vector(vector&& rhs) : vec(std::forward
(rhs.vec)) {} #endif When the wave driver is run, either BOOST_NO_CXX11_RVALUE_REFERENCES is defined, in which case the block of code gets left out, or else it isn't, in which case the block of code is left in. Both are wrong. What should happen is that the #if and #else directives should be present in wave's output.
I can keep wave from expanding certain named macros with the -N switch, but there doesn't seem to be a way to selectively keep wave from evaluating #if/#else directives. Or is there?
I asked Hartmut this same question before. IIRC, it's an issue that has no workaround (or fix) yet. I hope I am wrong.
Regards, -- Joel de Guzman http://www.ciere.com http://boost-spirit.com http://www.cycfi.com/
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Provided the code was only in an #if block used for pre-generation (or the code is *only* used for pre-gen), you could have wave produce that. E.g. use an object-like macro to get a non-macro-operator hash mark:
#if PREGENERATING_HEADERS
#define HASH #
HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
vector(vector&& rhs)
: vec(std::forward
How about making macros for #if, #else, #endif
BOOST_KEEP_UNTIL_WAVE_OUTPUT(if) -> #if
Then tell Wave not to translate it and translate it in the output.
the problem is that pp macros can't be expanded to pp directives.
John ________________________________________ From: Boost [boost-bounces@lists.boost.org] on behalf of Joel de Guzman [djowel@gmail.com] Sent: 21 January 2014 06:29 To: boost@lists.boost.org Subject: Re: [boost] [wave] preprocessor directives in output
On 1/21/14, 9:46 AM, Eric Niebler wrote:
I'm looking at automating the regeneration of Fusion's preprocess headers with the wave tool. Currently, it's impossible because of stuff like this (from container\vector\vector.hpp):
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) vector(vector&& rhs) : vec(std::forward
(rhs.vec)) {} #endif When the wave driver is run, either BOOST_NO_CXX11_RVALUE_REFERENCES is defined, in which case the block of code gets left out, or else it isn't, in which case the block of code is left in. Both are wrong. What should happen is that the #if and #else directives should be present in wave's output.
I can keep wave from expanding certain named macros with the -N switch, but there doesn't seem to be a way to selectively keep wave from evaluating #if/#else directives. Or is there?
I asked Hartmut this same question before. IIRC, it's an issue that has no workaround (or fix) yet. I hope I am wrong.
Regards, -- Joel de Guzman http://www.ciere.com http://boost-spirit.com http://www.cycfi.com/
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 1/20/2014 11:27 PM, pmenso57@comcast.net wrote:
Provided the code was only in an #if block used for pre-generation (or the code is *only* used for pre-gen), you could have wave produce that. E.g. use an object-like macro to get a non-macro-operator hash mark:
#if PREGENERATING_HEADERS #define HASH # HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) vector(vector&& rhs) : vec(std::forward
(rhs.vec)) {} HASH endif #endif
Clever, but sadly the code is not only used for pregeneration. It's possible to compile Fusion with the "don't use preprocessed headers" flag, in which case this header gets used directly. <sigh> -- Eric Niebler Boost.org http://www.boost.org
Eric Could that second use case use a different copy of the code? John -----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Eric Niebler Sent: 21 January 2014 16:13 To: boost@lists.boost.org Subject: Re: [boost] [wave] preprocessor directives in output On 1/20/2014 11:27 PM, pmenso57@comcast.net wrote:
Provided the code was only in an #if block used for pre-generation (or the code is *only* used for pre-gen), you could have wave produce that. E.g. use an object-like macro to get a non-macro-operator hash mark:
#if PREGENERATING_HEADERS #define HASH # HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) vector(vector&& rhs) : vec(std::forward
(rhs.vec)) {} HASH endif #endif
Clever, but sadly the code is not only used for pregeneration. It's possible to compile Fusion with the "don't use preprocessed headers" flag, in which case this header gets used directly. <sigh> -- Eric Niebler Boost.org http://www.boost.org _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
(John, please don't top-post on the Boost mailing list. See the Boost Discussion Policy at http://www.boost.org/community/policy.html) On 1/21/2014 8:25 AM, Fletcher, John P wrote:
On 21 January 2014 16:13, Eric Niebler wrote:
On 1/20/2014 11:27 PM, pmenso57@comcast.net wrote:
Provided the code was only in an #if block used for pre-generation (or the code is *only* used for pre-gen), you could have wave produce that. E.g. use an object-like macro to get a non-macro-operator hash mark:
#if PREGENERATING_HEADERS #define HASH # HASH if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) vector(vector&& rhs) : vec(std::forward
(rhs.vec)) {} HASH endif #endif Clever, but sadly the code is not only used for pregeneration. It's possible to compile Fusion with the "don't use preprocessed headers" flag, in which case this header gets used directly.
<sigh>
Eric
Could that second use case use a different copy of the code?
I figured this out. Using Paul's trick, I can do 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
On 1/22/14, 3:16 AM, Eric Niebler wrote:
I figured this out. Using Paul's trick, I can do 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
(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
Ugly as sin, but it seems to give the desired results.
Very clever indeed. Wow, I'm impressed. Yes, it is ugly, but if it gets the job done, then that's cool! Thank you for looking into this, Eric! Regards, -- Joel de Guzman http://www.ciere.com http://boost-spirit.com http://www.cycfi.com/
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) Regards, Paul Mensonides
On 01/21/2014 04:20 PM, pmenso57@comcast.net 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. Eric
On 01/21/2014 04:20 PM, pmenso57@comcast.net 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? Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu
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
On 01/21/2014 04:47 PM, Hartmut Kaiser wrote:
On 01/21/2014 04:20 PM, pmenso57@comcast.net 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
On 01/21/2014 04:20 PM, pmenso57@comcast.net 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
(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
(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
.
I predefines only the wave-specific macros (http://www.boost.org/doc/libs/1_55_0/libs/wave/doc/predefined_macros.html). Everything else has to be supplied by you. Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu
On 01/21/2014 05:48 PM, Hartmut Kaiser wrote:
Eric Niebler wrote:
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
. I predefines only the wave-specific macros (http://www.boost.org/doc/libs/1_55_0/libs/wave/doc/predefined_macros.html).
Everything else has to be supplied by you. OK. Looking at boost/config/select_compiler_config.hpp, I see that if no compiler is recognized, none of the BOOST_NO_* macros get defined. And wave is not a recognized "compiler". That's all I need, and the code I posted is fine, AFAIK. Eric
On 1/20/2014 11:38 PM, Thomas Heller wrote:
On 01/21/2014 08:17 AM, Fletcher, John P wrote:
How about making macros for #if, #else, #endif
BOOST_KEEP_UNTIL_WAVE_OUTPUT(if) -> #if
Then tell Wave not to translate it and translate it in the output.
the problem is that pp macros can't be expanded to pp directives.
Yes, unless the files get preprocessed *again* which they do in this case. -Paul
I'm looking at automating the regeneration of Fusion's preprocess headers with the wave tool. Currently, it's impossible because of stuff like this (from container\vector\vector.hpp):
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) vector(vector&& rhs) : vec(std::forward
(rhs.vec)) {} #endif When the wave driver is run, either BOOST_NO_CXX11_RVALUE_REFERENCES is defined, in which case the block of code gets left out, or else it isn't, in which case the block of code is left in. Both are wrong. What should happen is that the #if and #else directives should be present in wave's output.
I can keep wave from expanding certain named macros with the -N switch, but there doesn't seem to be a way to selectively keep wave from evaluating #if/#else directives. Or is there?
The only way I can see this resolved is to do:
// this has to go outside of a #pragma wave option(output: ...) block,
// allowing it to go unchanged into the 'generated' code
//
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
# define VECTOR_MOVE_CTOR() \
vector(vector&& rhs) : vec(std::forward
participants (8)
-
Edward Diener
-
Eric Niebler
-
Fletcher, John P
-
Hartmut Kaiser
-
Joel de Guzman
-
Paul Mensonides
-
pmenso57@comcast.net
-
Thomas Heller