[preprocessor] Dropping support for compilers that do not implement variadic macros
In lieu with Boost's decision regarding dropping support for C++03 compilation, I would like to drop support in the preprocessor library for preprocessors which do not implement variadic macros. Variadic macros were added in the C++11 standard, although a number of compilers supported them even before the official C++ standard. I will of course keep the same macro APIs, although deprecating non-variadic macro forms when alternate variadic macro forms exist. This will simplify Boost PP. Ideally, once Boost PP supports only preprocessors which implement variadic macros, Boost VMD can be added to Boost PP, for anyone who wants to use its functionality, and Boost VMD can then be retired.
Edward Diener wrote:
In lieu with Boost's decision regarding dropping support for C++03 compilation, I would like to drop support in the preprocessor library for preprocessors which do not implement variadic macros. Variadic macros were added in the C++11 standard, although a number of compilers supported them even before the official C++ standard. I will of course keep the same macro APIs, although deprecating non-variadic macro forms when alternate variadic macro forms exist. This will simplify Boost PP.
Which compilers will be affected?
On 9/14/2020 6:57 PM, Peter Dimov via Boost wrote:
Edward Diener wrote:
In lieu with Boost's decision regarding dropping support for C++03 compilation, I would like to drop support in the preprocessor library for preprocessors which do not implement variadic macros. Variadic macros were added in the C++11 standard, although a number of compilers supported them even before the official C++ standard. I will of course keep the same macro APIs, although deprecating non-variadic macro forms when alternate variadic macro forms exist. This will simplify Boost PP.
Which compilers will be affected?
Right now these compilers are considered by PP to not support variadic macros: gccxml nvcc when cuda is being used PathScale Digital Mars and Symantec C++ bcc32 metrowerks sun/oracle C++ < version 5.12 ( current oracle C++ version is 12.6 ) HP aC++ when not using EDG MPW C++ PGI when not using EDG Any compiler outside of gcc, clang, vc++, and Intel C++ 17.0 and after for which __cpluscplus is less than 201103L Of course saying that variadic macros are always assumed to be supported does not mean that any of the above will stop working if the compilers even still exist and do support variadic macros.
Edward Diener wrote:
Which compilers will be affected?
Right now these compilers are considered by PP to not support variadic macros:
gccxml nvcc when cuda is being used PathScale Digital Mars and Symantec C++ bcc32 metrowerks sun/oracle C++ < version 5.12 ( current oracle C++ version is 12.6 ) HP aC++ when not using EDG MPW C++ PGI when not using EDG
This doesn't sound that bad, as most of these compilers are dead, although I hope nvcc does support variadic macros nowadays.
On 9/15/2020 7:13 AM, Peter Dimov via Boost wrote:
Edward Diener wrote:
Which compilers will be affected?
Right now these compilers are considered by PP to not support variadic macros:
gccxml nvcc when cuda is being used PathScale Digital Mars and Symantec C++ bcc32 metrowerks sun/oracle C++ < version 5.12 ( current oracle C++ version is 12.6 ) HP aC++ when not using EDG MPW C++ PGI when not using EDG
This doesn't sound that bad, as most of these compilers are dead, although I hope nvcc does support variadic macros nowadays.
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings. The main culprits, for C++03 at the pedantic level, are that variadic macros are not supported and that empty macro arguments are undefined. The warnings do not impact the code from working properly, but of course the errors stop the code from working. So the gist is that if I change Boost PP to only support variadic macros an end-user compiling the preprocessor library headers at the gcc/clang C++03 level, whether directly or through many other Boost C++03 libraries which use Boost PP, and specifying either -pedantic or -pedantic-errros, will run into a bunch of warnings or a bunch of errors accordingly. Of course this will also depend on the Boost PP macros being used, since only a subset of macros when invoked uses variadic macros in their implementation. I still think that in line with Boost officially deprecating the C++03 level of compilation it will be advantageous to have Boost PP be a library which assumes variadic macro support and does not work properly in many instances without variadic macro support. My local branch for this shows much simplification of code and a much clearer use of macros in the library so unless there is a general outcry I am still determined to go ahead with this. I think the few people who may still be trying to use Boost libraries with gcc or clang at the C++03 level can be told to turn off -pedantic-errors if necessary. I will add a note to the documentation for Boost PP about this.
Em 17 de set de 2020, à(s) 23:09, Edward Diener via Boost
escreveu: On 9/15/2020 7:13 AM, Peter Dimov via Boost wrote:
Edward Diener wrote:
Which compilers will be affected?
Right now these compilers are considered by PP to not support variadic macros:
gccxml nvcc when cuda is being used PathScale Digital Mars and Symantec C++ bcc32 metrowerks sun/oracle C++ < version 5.12 ( current oracle C++ version is 12.6 ) HP aC++ when not using EDG MPW C++ PGI when not using EDG This doesn't sound that bad, as most of these compilers are dead, although I hope nvcc does support variadic macros nowadays.
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings.
Don’t warning disabling pragmas *around preprocessor definitions* solve the issue? Joaquín M López Muñoz
On 9/17/2020 6:10 PM, Joaquín M López Muñoz via Boost wrote:
Em 17 de set de 2020, à(s) 23:09, Edward Diener via Boost
escreveu: On 9/15/2020 7:13 AM, Peter Dimov via Boost wrote:
Edward Diener wrote:
Which compilers will be affected?
Right now these compilers are considered by PP to not support variadic macros:
gccxml nvcc when cuda is being used PathScale Digital Mars and Symantec C++ bcc32 metrowerks sun/oracle C++ < version 5.12 ( current oracle C++ version is 12.6 ) HP aC++ when not using EDG MPW C++ PGI when not using EDG This doesn't sound that bad, as most of these compilers are dead, although I hope nvcc does support variadic macros nowadays.
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings.
Don’t warning disabling pragmas *around preprocessor definitions* solve the issue?
They could but I would have to know when it is gcc or clang and when it is at the C+03 level. Compilers, including gcc, are notorious for not setting __cplusplus correctly, to determine C++03, and lots of compilers define __clang__ or __gnuc__. But you are theoretically correct and I will look at that.
On 18/09/2020 10:10, Joaquín M López Muñoz wrote:
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings.
Don’t warning disabling pragmas *around preprocessor definitions* solve the issue?
Depends on the specific warnings. Often the disables are needed at the call site instead or in addition. I've also seen some warnings raised by template code that are essentially impossible to pragma away (without disabling for the entire translation unit) as they get attributed to the instantiation "line" outside of all user code. Those are especially annoying.
On 9/17/2020 7:08 PM, Gavin Lambert via Boost wrote:
On 18/09/2020 10:10, Joaquín M López Muñoz wrote:
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings.
Don’t warning disabling pragmas *around preprocessor definitions* solve the issue?
Depends on the specific warnings. Often the disables are needed at the call site instead or in addition.
I've also seen some warnings raised by template code that are essentially impossible to pragma away (without disabling for the entire translation unit) as they get attributed to the instantiation "line" outside of all user code. Those are especially annoying.
As you presciently guessed it is impossible to change a "-Wpedantic" to either a "warning" if -pedantic-errors is specified or to an "ignore" if either -pedantic or -pedantic-errors is specified. I tried: #pragma GCC diagnostic ignore "-Wpedantic" or #pragma GCC diagnostic warning "-Wpedantic" and neither does anything.
On 18/09/2020 13:07, Edward Diener wrote:
I tried:
#pragma GCC diagnostic ignore "-Wpedantic"
or
#pragma GCC diagnostic warning "-Wpedantic"
and neither does anything.
-Wpedantic isn't a thing; you need to name the specific individual warnings that actually occur. These names should be included in the compiler output. And as Andrey noted, to do this properly you'd need to push/pop the warning status to avoid affecting the rest of the translation unit, including user code. (This means that at best you can only disable warnings for internal usage, not for user usage. But that's as it should be. And you should verify that whatever you do *doesn't* hide the warnings in user code, otherwise you're just creating a different kind of problem.)
On 9/17/2020 10:48 PM, Gavin Lambert via Boost wrote:
On 18/09/2020 13:07, Edward Diener wrote:
I tried:
#pragma GCC diagnostic ignore "-Wpedantic"
or
#pragma GCC diagnostic warning "-Wpedantic"
and neither does anything.
-Wpedantic isn't a thing; you need to name the specific individual warnings that actually occur. These names should be included in the compiler output.
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragma...
And as Andrey noted, to do this properly you'd need to push/pop the warning status to avoid affecting the rest of the translation unit, including user code.
(This means that at best you can only disable warnings for internal usage, not for user usage. But that's as it should be. And you should verify that whatever you do *doesn't* hide the warnings in user code, otherwise you're just creating a different kind of problem.)
On 18/09/2020 16:35, Edward Diener wrote:
On 9/17/2020 10:48 PM, Gavin Lambert wrote:
On 18/09/2020 13:07, Edward Diener wrote:
I tried:
#pragma GCC diagnostic ignore "-Wpedantic"
or
#pragma GCC diagnostic warning "-Wpedantic"
and neither does anything.
-Wpedantic isn't a thing; you need to name the specific individual warnings that actually occur. These names should be included in the compiler output.
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragma...
That link doesn't contradict anything I said. Although perhaps *you* should take another look at it, in particular at the part where it said how to check which ones can actually be changed. (And perhaps also at the part where it says how to apply these at preprocessing time, although I suspect it's not going to help too much in this case since the issue is with the arguments.)
On 9/18/2020 1:28 AM, Gavin Lambert via Boost wrote:
On 18/09/2020 16:35, Edward Diener wrote:
On 9/17/2020 10:48 PM, Gavin Lambert wrote:
On 18/09/2020 13:07, Edward Diener wrote:
I tried:
#pragma GCC diagnostic ignore "-Wpedantic"
or
#pragma GCC diagnostic warning "-Wpedantic"
and neither does anything.
-Wpedantic isn't a thing; you need to name the specific individual warnings that actually occur. These names should be included in the compiler output.
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragma...
That link doesn't contradict anything I said.
Although perhaps *you* should take another look at it, in particular at the part where it said how to check which ones can actually be changed.
(And perhaps also at the part where it says how to apply these at preprocessing time, although I suspect it's not going to help too much in this case since the issue is with the arguments.)
My point is that I use whatever names which show up in the compiler output, such as "-Wvariadic-macros" or "-Wpedantic", and it does nothing, so evidently those are among the warning options which can not be changed by the #pragma GCC diagnostic.
On Fri, Sep 18, 2020 at 1:10 AM Joaquín M López Muñoz via Boost
Em 17 de set de 2020, à(s) 23:09, Edward Diener via Boost
escreveu: On 9/15/2020 7:13 AM, Peter Dimov via Boost wrote:
Edward Diener wrote:
Which compilers will be affected?
Right now these compilers are considered by PP to not support variadic macros:
gccxml nvcc when cuda is being used PathScale Digital Mars and Symantec C++ bcc32 metrowerks sun/oracle C++ < version 5.12 ( current oracle C++ version is 12.6 ) HP aC++ when not using EDG MPW C++ PGI when not using EDG This doesn't sound that bad, as most of these compilers are dead, although I hope nvcc does support variadic macros nowadays.
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings.
Don’t warning disabling pragmas *around preprocessor definitions* solve the issue?
Note that gcc supports push/pop pragmas only since gcc 4.6. Before that you can't disable a warning without affecting the user's code compilation. I'm also not sure disabling the warning around a macro *definition* works.
On 9/17/2020 8:20 PM, Andrey Semashev via Boost wrote:
On Fri, Sep 18, 2020 at 1:10 AM Joaquín M López Muñoz via Boost
wrote: Em 17 de set de 2020, à(s) 23:09, Edward Diener via Boost
escreveu: On 9/15/2020 7:13 AM, Peter Dimov via Boost wrote:
Edward Diener wrote:
Which compilers will be affected?
Right now these compilers are considered by PP to not support variadic macros:
gccxml nvcc when cuda is being used PathScale Digital Mars and Symantec C++ bcc32 metrowerks sun/oracle C++ < version 5.12 ( current oracle C++ version is 12.6 ) HP aC++ when not using EDG MPW C++ PGI when not using EDG This doesn't sound that bad, as most of these compilers are dead, although I hope nvcc does support variadic macros nowadays.
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings.
Don’t warning disabling pragmas *around preprocessor definitions* solve the issue?
Note that gcc supports push/pop pragmas only since gcc 4.6. Before that you can't disable a warning without affecting the user's code compilation.
I'm also not sure disabling the warning around a macro *definition* works.
It does not work either around the macro definition or around the macro invocation.
On Fri, Sep 18, 2020 at 12:08 AM Edward Diener via Boost
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings.
I still think that in line with Boost officially deprecating the C++03 level of compilation it will be advantageous to have Boost PP be a library which assumes variadic macro support and does not work properly in many instances without variadic macro support. My local branch for this shows much simplification of code and a much clearer use of macros in the library so unless there is a general outcry I am still determined to go ahead with this. I think the few people who may still be trying to use Boost libraries with gcc or clang at the C++03 level can be told to turn off -pedantic-errors if necessary. I will add a note to the documentation for Boost PP about this.
Although I'm probably in the minority, I still think having C++11 PP library (be that Boost.PP2 or Boost.VMD) would be better.
Edward Diener wrote:
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings. The main culprits, for C++03 at the pedantic level, are that variadic macros are not supported and that empty macro arguments are undefined.
Note that empty arguments for __VA_ARGS__ aren't allowed by C99, so clang -pedantic warns about them even in C++20 mode (even though C++20 has __VA_OPT__.) <source>:3:4: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments] clang -pedantic is way too pedantic, if you ask me.
On 9/17/2020 9:46 PM, Peter Dimov via Boost wrote:
Edward Diener wrote:
I did discover that if gcc or clang is compiled at the C++03 level with -pedantic there will be a ton of warnings, and if with -pedantic-errros there will be a ton of errors for those warnings. The main culprits, for C++03 at the pedantic level, are that variadic macros are not supported and that empty macro arguments are undefined.
Note that empty arguments for __VA_ARGS__ aren't allowed by C99, so clang -pedantic warns about them even in C++20 mode (even though C++20 has __VA_OPT__.)
<source>:3:4: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
clang -pedantic is way too pedantic, if you ask me.
The "empty macro arguments are undefined" in C++03 when -pedantic is used refers to the fact that you can not pass nothing to an argument: #define AMAC(x) x AMAC() which is totally legal in C++11 on up. I actually did not realize that it was not legal in C++03, according to gcc/clang. Similarly: #define AMACV(...) __VA_ARGS__ AMACV() is also totally legal, except for C++03 evidently. #define AMACV2(x,...) x __VA_ARGS__ AMACV2(arg,) is fine, except for C++03 evidently but: AMACV2(arg) is fine only in C++20 on up. I am still not sure why passing nothing is illegal in C++03, as opposed to C++11 on up, but if both gcc and clang says it is not I guess they are right. I agree that -pedantic in clang and gcc is way too pedantic.
On 9/14/2020 6:57 PM, Peter Dimov via Boost wrote:
Edward Diener wrote:
In lieu with Boost's decision regarding dropping support for C++03 compilation, I would like to drop support in the preprocessor library for preprocessors which do not implement variadic macros. Variadic macros were added in the C++11 standard, although a number of compilers supported them even before the official C++ standard. I will of course keep the same macro APIs, although deprecating non-variadic macro forms when alternate variadic macro forms exist. This will simplify Boost PP.
Which compilers will be affected?
I forgot to add that VC++ prior to VS2005 is considered to not support variadic macros.
On 9/15/2020 7:15 AM, Peter Dimov via Boost wrote:
Edward Diener wrote:
I forgot to add that VC++ prior to VS2005 is considered to not support variadic macros.
I don't think anyone cares about msvc-7.1, msvc-8.0, or even msvc-9.0 now (when Boost doesn't build on msvc-9.0, nobody notices, even though Appveyor still has it).
I am going to go ahead and assume all compilers have support for variadic macros for the next Boost release. It's time, and should not impact any other libaries which use Boost PP. I will of course update 'develop' first before merging the changes to 'master'.
On 2020-09-15 01:52, Edward Diener via Boost wrote:
In lieu with Boost's decision regarding dropping support for C++03 compilation, I would like to drop support in the preprocessor library for preprocessors which do not implement variadic macros. Variadic macros were added in the C++11 standard, although a number of compilers supported them even before the official C++ standard. I will of course keep the same macro APIs, although deprecating non-variadic macro forms when alternate variadic macro forms exist. This will simplify Boost PP. Ideally, once Boost PP supports only preprocessors which implement variadic macros, Boost VMD can be added to Boost PP, for anyone who wants to use its functionality, and Boost VMD can then be retired.
Why not make Boost.Preprocessor2 or extend Boost.VMD? Boost.Preprocessor is used quite a lot throughout Boost, not in the least part specifically to support C++03. If it stops being C++03 compatible, this will mean most of Boost will stop as well. At that point the dependent libraries may need to reevaluate if they still want to use Boost.Preprocessor and possibly either fork it or replace it with C++11 constructs. In some instances, like Boost.MPL, Boost.Variant, this may make the library pointless because there already are C++11 and newer replacements.
On 9/14/2020 7:38 PM, Andrey Semashev via Boost wrote:
On 2020-09-15 01:52, Edward Diener via Boost wrote:
In lieu with Boost's decision regarding dropping support for C++03 compilation, I would like to drop support in the preprocessor library for preprocessors which do not implement variadic macros. Variadic macros were added in the C++11 standard, although a number of compilers supported them even before the official C++ standard. I will of course keep the same macro APIs, although deprecating non-variadic macro forms when alternate variadic macro forms exist. This will simplify Boost PP. Ideally, once Boost PP supports only preprocessors which implement variadic macros, Boost VMD can be added to Boost PP, for anyone who wants to use its functionality, and Boost VMD can then be retired.
Why not make Boost.Preprocessor2 or extend Boost.VMD?
Boost.Preprocessor is used quite a lot throughout Boost, not in the least part specifically to support C++03. If it stops being C++03 compatible, this will mean most of Boost will stop as well.
My proposed change does not mean that PP stops supporting C++03. Lots of compilers supported variadic macros even when compiling in C++03 mode, ie. gcc and clang and vc++ starting with VS2005 being the most prominent. The few that actually did not support variadic macros in C++03 mode should not be used with future Boost by anybody; they are really ancient. Isn't that what discouraging compiling in C++03 mode is all about, so that ancient compilers still supporting c++03 should not be used by developers as Boost goes forward.
At that point the dependent libraries may need to reevaluate if they still want to use Boost.Preprocessor and possibly either fork it or replace it with C++11 constructs. In some instances, like Boost.MPL, Boost.Variant, this may make the library pointless because there already are C++11 and newer replacements.
On 2020-09-15 05:18, Edward Diener via Boost wrote:
On 9/14/2020 7:38 PM, Andrey Semashev via Boost wrote:
Boost.Preprocessor is used quite a lot throughout Boost, not in the least part specifically to support C++03. If it stops being C++03 compatible, this will mean most of Boost will stop as well.
My proposed change does not mean that PP stops supporting C++03. Lots of compilers supported variadic macros even when compiling in C++03 mode, ie. gcc and clang and vc++ starting with VS2005 being the most prominent. The few that actually did not support variadic macros in C++03 mode should not be used with future Boost by anybody; they are really ancient.
Ok, so it doesn't look as scary as it initially did. Thank you.
Isn't that what discouraging compiling in C++03 mode is all about, so that ancient compilers still supporting c++03 should not be used by developers as Boost goes forward.
I actually don't know what the incentive to actively drop C++03 is. (Disclosure: I write C++17 on a daily basis and I realize C++03 is limiting in some ways. It is not in others, and some written code can be made trivially compatible with C++03. Granted, this may not be the case with Boost.PP, but that code is already written and I suspect requires little maintenance. Also, in my C++17 code base I'm using some great C++03 libraries, including Boost, and I see nothing wrong about it. Please, don't consider this paragraph as an invitation to C++03 vs. C++11 argument.)
On 9/15/2020 6:01 AM, Andrey Semashev via Boost wrote:
On 2020-09-15 05:18, Edward Diener via Boost wrote:
On 9/14/2020 7:38 PM, Andrey Semashev via Boost wrote:
Boost.Preprocessor is used quite a lot throughout Boost, not in the least part specifically to support C++03. If it stops being C++03 compatible, this will mean most of Boost will stop as well.
My proposed change does not mean that PP stops supporting C++03. Lots of compilers supported variadic macros even when compiling in C++03 mode, ie. gcc and clang and vc++ starting with VS2005 being the most prominent. The few that actually did not support variadic macros in C++03 mode should not be used with future Boost by anybody; they are really ancient.
Ok, so it doesn't look as scary as it initially did. Thank you.
Isn't that what discouraging compiling in C++03 mode is all about, so that ancient compilers still supporting c++03 should not be used by developers as Boost goes forward.
I actually don't know what the incentive to actively drop C++03 is.
(Disclosure: I write C++17 on a daily basis and I realize C++03 is limiting in some ways. It is not in others, and some written code can be made trivially compatible with C++03. Granted, this may not be the case with Boost.PP, but that code is already written and I suspect requires little maintenance.
It will make Boost PP code much cleaner to understand if support for non-variadic macros is dropped. I still will keep whatever workarounds are needed for the VC++ non-standard default preprocessor. Now that Microsoft has a new C++ standard preprocessor, hopefully programmers will switch to it and those old workarounds can also go away some day.
Also, in my C++17 code base I'm using some great C++03 libraries, including Boost, and I see nothing wrong about it. Please, don't consider this paragraph as an invitation to C++03 vs. C++11 argument.)
Why not make Boost.Preprocessor2 or extend Boost.VMD? I'd not add yet another library doing pretty much the same as an existing one. Deleting complicated code to reduce maintenance burden is reasonable. Boost.Preprocessor is used quite a lot throughout Boost, not in the least part specifically to support C++03. If it stops being C++03 compatible, this will mean most of Boost will stop as well. At that point the dependent libraries may need to reevaluate if they still want to use Boost.Preprocessor and possibly either fork it or replace it with C++11 constructs. In some instances, like Boost.MPL, Boost.Variant, this may make the library pointless because there already are C++11 and newer replacements.
From a "legal" perspective: It was made clear that by now any library is free to "drop support for C++03" and there is not obligation to do or don't (see all the many discussions about Boost C++11) I'd actually welcome the change. As Edward mentioned dropping variadic macros is not yet dropping C++03, as many compilers did support those well before C++11, although e.g. GCC issues warnings (which I'd suggest to suppress in Boost.PP) If that move makes libraries obsolete, I'd see that as a bonus, but I don't think so, yet. However maybe reconsidering the relevance of such libs would be a good thing. E.g. MPL without non-variadic macros is still useful/working and used by many others. The interfaces will be kept as-is, so no need to remove although it makes sense to switch from it if possible due to its compile time hit.
participants (6)
-
Alexander Grund
-
Andrey Semashev
-
Edward Diener
-
Gavin Lambert
-
Joaquín M López Muñoz
-
Peter Dimov