[config] Boost PP and variadic macros

This is largely directed to John Maddock, the maintainer of config, but of course anyone else can respond who is interested. I have been working to integrate my VMD library, and essentially variadic macro support, into Boost PP, with help and discussion offline of Paul Mensonides. I am now at the testing phase and all is now going well. This is currently being done in a separate library but when Paul and I are satisfied we intend to update the trunk with our changes. The library is at https://svn.boost.org/svn/boost/branches/pplib/variadics. One problem that I have can be explained by the fact that Boost PP currently does not depend on any other Boost library, not even Boost config. The reason for this is that Boost PP has been designed to work with C compilers ( or C++ compilers in C mode ) as well as C++ compilers. This means that the code to detect variadic macro support in Boost is duplicated in two places, both in config, which I basically started with the blessing of John Maddock with the BOOST_NO_VARIADIC_MACROS macro, and in Boost PP in a configuration file which I have coded and essentially duplicates the code in config for variadic macro support. I do not like this. Duplicating functionality in two different places, even as simple as determining variadic macro support for compilers, is error prone and a maintenance problem. Changes in one place have to be done in the other, and this would need to constantly be tracked. My initial thought was to see if config could work with C compilers, but all investigation there has led me to believe that it would be too many unnecessary changes to config, would complicate config greatly, would need extensive testing against all compilers, and that since config is central to all of Boost such a potential massive change to it it is a bad idea. So my current thought is to remove the code in config which tests for variadic macro support for a given compiler, to determine if BOOST_NO_VARIADIC_MACROS should be set, into a separate header file for each compiler which might set BOOST_NO_VARIADIC_MACROS, and then #include that header file in the compiler's header file, at the place where currently the setting of BOOST_NO_VARIADIC_MACROS exists ( or possible at the end ). The separate header file itself for testing variadic macro support is easily C compatible and I could use it in my Boost PP configuration file. This would eliminate duplication of the code to test for variadic macro support in config and Boost PP while keeping the goal of allowing Boost PP to still work with C compilers. Is this possible/desirable as far as config goes ? It would only affect the current code for setting BOOST_NO_VARIADIC_MACROS, hardly a Boost world-shaking event, and can easily be done by me and tested in regression tests. If it is, one further consideration is that the code in the Boost PP configuration file still would have to internally duplicate the checking and order of each compiler in the 'select_compiler_config.h' in config, but this is at least much better, and much less of a maintenance problem for Boost PP, than having to duplicate the code for checking for variadic macro support itself. Even this could be worked around, with a probably undesirable change to 'select_compiler_config.h', which I will proceed to suggest nonetheless. If we could add to that file another set of #defines for the corresponding variadic macro checking header file for each compiler that needs it. Something like: #define BOOST_COMPILER_CONFIG_NVM "boost/config/compiler/somecompiler_nvm.hpp" then in my Boost PP config header file I could go: #include <boost/config/select_compiler_config.hpp> #ifdef BOOST_COMPILER_CONFIG_NVM #include BOOST_COMPILER_CONFIG_NVM #endif and I could then check BOOST_NO_VARIADIC_MACROS and this will work for C compilers ( 'select_compiler_config.hpp' itself has nothing related to C++ and should work with any C compiler AFAICS ). But I would understand that littering 'select_compiler_config.hpp' with another set of #defines just to satisfy my need in Boost PP may not be acceptable to the clean design of that file, even if it would eliminate my need to reduplicate its logic in the Boost PP configuration file for variadic macro support in Boost PP which I have created.

On Sun, 03 Apr 2011 11:58:58 -0400 Edward Diener <eldiener@tropicsoft.com> wrote:
[...] My initial thought was to see if config could work with C compilers, but all investigation there has led me to believe that it would be too many unnecessary changes to config, would complicate config greatly, would need extensive testing against all compilers, and that since config is central to all of Boost such a potential massive change to it it is a bad idea. [...]
What about simply wrapping everything in config, except the varadic stuff, in an "#ifdef __cplusplus"? It would be an unobtrusive change, and that define is required by every C++ standard I've seen (note: I've only seen working drafts, not the final copies, though I don't expect that part has changed). I know that even Borland's compilers (arguably the most problematic ones in common use today) have defined that since Turbo C++ 1.0 in the eighties. -- Chad Nelson Oak Circle Software, Inc. * * *

On 4/3/2011 12:46 PM, Chad Nelson wrote:
On Sun, 03 Apr 2011 11:58:58 -0400 Edward Diener<eldiener@tropicsoft.com> wrote:
[...] My initial thought was to see if config could work with C compilers, but all investigation there has led me to believe that it would be too many unnecessary changes to config, would complicate config greatly, would need extensive testing against all compilers, and that since config is central to all of Boost such a potential massive change to it it is a bad idea. [...]
What about simply wrapping everything in config, except the varadic stuff, in an "#ifdef __cplusplus"?
That was the original thought. But it would mean testing each compiler/version to make sure that __cplusplus was actually being set when compiling a C++ program.
It would be an unobtrusive change, and that define is required by every C++ standard I've seen (note: I've only seen working drafts, not the final copies, though I don't expect that part has changed).
It might be unobtrusive but there are very many config header files in which one would have to do that. Even doing it just for each compiler's header file would mean that each compiler would have to be tested which config supports. I do not think we even have every compiler which config supports being tested regularly, but I may be wrong.
I know that even Borland's compilers (arguably the most problematic ones in common use today) have defined that since Turbo C++ 1.0 in the eighties.
There are other compilers "supported" by config which are even less common than Borland.

[...] My initial thought was to see if config could work with C compilers, but all investigation there has led me to believe that it would be too many unnecessary changes to config, would complicate config greatly, would need extensive testing against all compilers, and that since config is central to all of Boost such a potential massive change to it it is a bad idea. [...]
What about simply wrapping everything in config, except the varadic stuff, in an "#ifdef __cplusplus"?
That was the original thought. But it would mean testing each compiler/version to make sure that __cplusplus was actually being set when compiling a C++ program.
__cplusplus is absolutely required to be set for C++ compilation, I've never heard of a compiler that doesn't set it in C++ mode.
It would be an unobtrusive change, and that define is required by every C++ standard I've seen (note: I've only seen working drafts, not the final copies, though I don't expect that part has changed).
It might be unobtrusive but there are very many config header files in which one would have to do that. Even doing it just for each compiler's header file would mean that each compiler would have to be tested which config supports. I do not think we even have every compiler which config supports being tested regularly, but I may be wrong.
True enough, but there weren't many changes required: try SVN Trunk now, Boost.Config should compile in C mode as well as C++ mode now. Tested locally with msvc, gcc (all the versions I could find!), intel and sun. I've also added a C-language test case, and manually inspected the compiler and platform config files for C++ specific code. Lets see how that works out... HTH, John.

On 4/3/2011 2:01 PM, John Maddock wrote:
[...] My initial thought was to see if config could work with C compilers, but all investigation there has led me to believe that it would be too many unnecessary changes to config, would complicate config greatly, would need extensive testing against all compilers, and that since config is central to all of Boost such a potential massive change to it it is a bad idea. [...]
What about simply wrapping everything in config, except the varadic stuff, in an "#ifdef __cplusplus"?
That was the original thought. But it would mean testing each compiler/version to make sure that __cplusplus was actually being set when compiling a C++ program.
__cplusplus is absolutely required to be set for C++ compilation, I've never heard of a compiler that doesn't set it in C++ mode.
I believe you, but I did not know if you wanted this in config and/or trusted all the compilers config supports to implement this correctly. Of course I absolutely know they should...
It would be an unobtrusive change, and that define is required by every C++ standard I've seen (note: I've only seen working drafts, not the final copies, though I don't expect that part has changed).
It might be unobtrusive but there are very many config header files in which one would have to do that. Even doing it just for each compiler's header file would mean that each compiler would have to be tested which config supports. I do not think we even have every compiler which config supports being tested regularly, but I may be wrong.
True enough, but there weren't many changes required: try SVN Trunk now, Boost.Config should compile in C mode as well as C++ mode now. Tested locally with msvc, gcc (all the versions I could find!), intel and sun. I've also added a C-language test case, and manually inspected the compiler and platform config files for C++ specific code. Lets see how that works out...
Thank you very much. I will look at it, and report back my changes to allow variadic macro support checking without the need to have __cplusplus defined ( in other words for a C compiler ).

On 4/3/2011 2:01 PM, John Maddock wrote:
It might be unobtrusive but there are very many config header files in which one would have to do that. Even doing it just for each compiler's header file would mean that each compiler would have to be tested which config supports. I do not think we even have every compiler which config supports being tested regularly, but I may be wrong.
True enough, but there weren't many changes required: try SVN Trunk now, Boost.Config should compile in C mode as well as C++ mode now. Tested locally with msvc, gcc (all the versions I could find!), intel and sun. I've also added a C-language test case, and manually inspected the compiler and platform config files for C++ specific code. Lets see how that works out...
I have some more patches. Do I attach them here or send them to you ?

It might be unobtrusive but there are very many config header files in which one would have to do that. Even doing it just for each compiler's header file would mean that each compiler would have to be tested which config supports. I do not think we even have every compiler which config supports being tested regularly, but I may be wrong.
True enough, but there weren't many changes required: try SVN Trunk now, Boost.Config should compile in C mode as well as C++ mode now. Tested locally with msvc, gcc (all the versions I could find!), intel and sun. I've also added a C-language test case, and manually inspected the compiler and platform config files for C++ specific code. Lets see how that works out...
I have some more patches. Do I attach them here or send them to you ?
Either is fine. John.

On 4/4/2011 4:03 AM, John Maddock wrote:
It might be unobtrusive but there are very many config header files in which one would have to do that. Even doing it just for each compiler's header file would mean that each compiler would have to be tested which config supports. I do not think we even have every compiler which config supports being tested regularly, but I may be wrong.
True enough, but there weren't many changes required: try SVN Trunk now, Boost.Config should compile in C mode as well as C++ mode now. Tested locally with msvc, gcc (all the versions I could find!), intel and sun. I've also added a C-language test case, and manually inspected the compiler and platform config files for C++ specific code. Lets see how that works out...
I have some more patches. Do I attach them here or send them to you ?
Either is fine.
Attached are some more patches.

True enough, but there weren't many changes required: try SVN Trunk now, Boost.Config should compile in C mode as well as C++ mode now. Tested locally with msvc, gcc (all the versions I could find!), intel and sun. I've also added a C-language test case, and manually inspected the compiler and platform config files for C++ specific code. Lets see how that works out...
I have some more patches. Do I attach them here or send them to you ?
Either is fine.
Attached are some more patches.
Unless I'm missing something, those shouldn't be needed - I deliberately disabled std lib configuration when __cplusplus isn't set as it makes no real sense in C mode? Cheers, John.

On 4/4/2011 10:57 AM, John Maddock wrote:
True enough, but there weren't many changes required: try SVN Trunk now, Boost.Config should compile in C mode as well as C++ mode now. Tested locally with msvc, gcc (all the versions I could find!), intel and sun. I've also added a C-language test case, and manually inspected the compiler and platform config files for C++ specific code. Lets see how that works out...
I have some more patches. Do I attach them here or send them to you ?
Either is fine.
Attached are some more patches.
Unless I'm missing something, those shouldn't be needed - I deliberately disabled std lib configuration when __cplusplus isn't set as it makes no real sense in C mode?
Agreed. But you do have checks for __cpluscplus in some of the other config/stdlib header files so I made those patches to conform. Maybe you could now remove those others, and just ignore those patches I sent. Attached are two more, which are relevant, and one which is a cosmetic spelling change which confused me when I first read it and means almost the opposite of what you meant to say in a comment. These are the last I found.

Unless I'm missing something, those shouldn't be needed - I deliberately disabled std lib configuration when __cplusplus isn't set as it makes no real sense in C mode?
Agreed. But you do have checks for __cpluscplus in some of the other config/stdlib header files so I made those patches to conform. Maybe you could now remove those others, and just ignore those patches I sent.
No, the point is that the compiler and platform configuration headers are included in C mode, but the C++ std lib ones are not (as there's no point).
Attached are two more, which are relevant, and one which is a cosmetic spelling change which confused me when I first read it and means almost the opposite of what you meant to say in a comment. These are the last I found.
Thanks, applied, John.

On 4/5/2011 4:22 AM, John Maddock wrote:
Unless I'm missing something, those shouldn't be needed - I deliberately disabled std lib configuration when __cplusplus isn't set as it makes no real sense in C mode?
Agreed. But you do have checks for __cpluscplus in some of the other config/stdlib header files so I made those patches to conform. Maybe you could now remove those others, and just ignore those patches I sent.
No, the point is that the compiler and platform configuration headers are included in C mode, but the C++ std lib ones are not (as there's no point).
I was not clear when I referred to "those others" above. What I meant by it is that you have checks for __cpluscplus in some places within the C++ std lib config headers, but they can be removed because you disabled std lib configuration when __cpluscplus is not set. Attached are the patch files for those changes for removing the checks for __cpluscplus in the std lib headers, if you want to apply them.

No, the point is that the compiler and platform configuration headers are included in C mode, but the C++ std lib ones are not (as there's no point).
I was not clear when I referred to "those others" above. What I meant by it is that you have checks for __cpluscplus in some places within the C++ std lib config headers, but they can be removed because you disabled std lib configuration when __cpluscplus is not set. Attached are the patch files for those changes for removing the checks for __cpluscplus in the std lib headers, if you want to apply them.
Got it, reverted those changes, John.

On 03/04/2011 17:58, Edward Diener wrote:
This means that the code to detect variadic macro support in Boost is duplicated in two places, both in config, which I basically started with the blessing of John Maddock with the BOOST_NO_VARIADIC_MACROS macro, and in Boost PP in a configuration file which I have coded and essentially duplicates the code in config for variadic macro support.
I do not like this. Duplicating functionality in two different places, even as simple as determining variadic macro support for compilers, is error prone and a maintenance problem. Changes in one place have to be done in the other, and this would need to constantly be tracked.
Does it detect the MSVC bug that severely restricts the use of variadic macros with that compiler?

On 4/3/2011 2:22 PM, Mathias Gaunard wrote:
On 03/04/2011 17:58, Edward Diener wrote:
This means that the code to detect variadic macro support in Boost is duplicated in two places, both in config, which I basically started with the blessing of John Maddock with the BOOST_NO_VARIADIC_MACROS macro, and in Boost PP in a configuration file which I have coded and essentially duplicates the code in config for variadic macro support.
I do not like this. Duplicating functionality in two different places, even as simple as determining variadic macro support for compilers, is error prone and a maintenance problem. Changes in one place have to be done in the other, and this would need to constantly be tracked.
Does it detect the MSVC bug that severely restricts the use of variadic macros with that compiler?
I am aware of a problem with VC++ and variadic macros and already addressed it in my VMD library by finding an effective workaround. The same technique to workaround the VC++ problem is in Boost PP with my work to add variadic macro support for it. If you still find a specific proble with VMD and VC++, please report it to me. The same goes for the work I am doing now to bring variadic macros to Boost PP.

On 03/04/2011 20:56, Edward Diener wrote:
I am aware of a problem with VC++ and variadic macros and already addressed it in my VMD library by finding an effective workaround. The same technique to workaround the VC++ problem is in Boost PP with my work to add variadic macro support for it. If you still find a specific proble with VMD and VC++, please report it to me. The same goes for the work I am doing now to bring variadic macros to Boost PP.
I would be very interested in knowing what your workaround is for the token pasting problem of MSVC, which prevents things like the popular PP_NARG[1] macro from working. [1] http://groups.google.com/group/comp.std.c/msg/12dd93fe6cb5f5e5

On 4/3/2011 3:47 PM, Mathias Gaunard wrote:
On 03/04/2011 20:56, Edward Diener wrote:
I am aware of a problem with VC++ and variadic macros and already addressed it in my VMD library by finding an effective workaround. The same technique to workaround the VC++ problem is in Boost PP with my work to add variadic macro support for it. If you still find a specific proble with VMD and VC++, please report it to me. The same goes for the work I am doing now to bring variadic macros to Boost PP.
I would be very interested in knowing what your workaround is for the token pasting problem of MSVC, which prevents things like the popular PP_NARG[1] macro from working.
I am aware of that problem and it is the one I solved. In my VMD library look at the vmd_detail.hpp header file and the versions of VMD_DETAIL_DATA_SIZE(...) and VMD_DETAIL_DATA_ELEM(n,...) for BOOST_MSVC. Exactly why my workaround solves the problem for VC++ I do not know ( or really care given that the VC++ preprocessor is hardly standard conforming ) but it does for the functionality desired.
[1] http://groups.google.com/group/comp.std.c/msg/12dd93fe6cb5f5e5
I also credit Laurent Deniau in my acknowledgments.
participants (5)
-
Chad Nelson
-
Edward Diener
-
John Maddock
-
Mathias Gaunard
-
Steven Watanabe