Defining compilers suggestion

It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as: #define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER) where SOME_COMPILER might be VC71,GCC40 etc. Then in code one could see: #if defined(BOOST_COMPILER_VC71) etc. rather than the less understandable #if defined(MSC_VER == nnnn) etc. I would just like to see more readability in the Boost code regarding compiler workarounds. I am also aware their is a workaround macro, but even that deals in compiler preprocessor tags rather than a more readable compiler version. I am aware that many workarounds have to deal with versions before or after a certain version number but even that can be made more readable by macros which tell one the actual compiler which is involved. I realize I am just a reader of Boost code and not a Boost developer but I think this suggestion would make for a little more readable code in its own small way.

Edward Diener wrote:
It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as:
#define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER)
where SOME_COMPILER might be VC71,GCC40 etc.
Then in code one could see:
#if defined(BOOST_COMPILER_VC71) etc.
rather than the less understandable
#if defined(MSC_VER == nnnn) etc.
I would just like to see more readability in the Boost code regarding compiler workarounds. I am also aware their is a workaround macro, but even that deals in compiler preprocessor tags rather than a more readable compiler version. I am aware that many workarounds have to deal with versions before or after a certain version number but even that can be made more readable by macros which tell one the actual compiler which is involved.
I realize I am just a reader of Boost code and not a Boost developer but I think this suggestion would make for a little more readable code in its own small way.
How about these? #define BOOST_COMPILER_WITH_VERSION(compiler,version) \ (compiler == version) #define BOOST_COMPILER_ABOVE_VERSION(compiler,version) \ (compiler > version) #define BOOST_COMPILER_FROM_VERSION(compiler,version) \ (compiler >= version) #define BOOST_COMPILER_BELOW_VERSION(compiler,version) \ ((compiler != 0) && (compiler < version)) #define BOOST_COMPILER_UP_TO_VERSION(compiler,vesionr) \ ((compiler != 0) && (compiler <= version)) #define BOOST_COMPILER_FROM_TO_VERSION(compiler,min_version,max_version) \ ((compiler != 0) && ((compiler >= min_version) && (compiler <= max_version))) Example: #if BOOST_COMPILER_BELOW_VERSION(BOOST_MSVC,1400) ... #endif Regards, Tobias

Tobias Schwinger wrote:
Edward Diener wrote:
It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as:
#define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER)
where SOME_COMPILER might be VC71,GCC40 etc.
Then in code one could see:
#if defined(BOOST_COMPILER_VC71) etc.
rather than the less understandable
#if defined(MSC_VER == nnnn) etc.
I would just like to see more readability in the Boost code regarding compiler workarounds. I am also aware their is a workaround macro, but even that deals in compiler preprocessor tags rather than a more readable compiler version. I am aware that many workarounds have to deal with versions before or after a certain version number but even that can be made more readable by macros which tell one the actual compiler which is involved.
I realize I am just a reader of Boost code and not a Boost developer but I think this suggestion would make for a little more readable code in its own small way.
How about these?
#define BOOST_COMPILER_WITH_VERSION(compiler,version) \ (compiler == version)
#define BOOST_COMPILER_ABOVE_VERSION(compiler,version) \ (compiler > version)
#define BOOST_COMPILER_FROM_VERSION(compiler,version) \ (compiler >= version)
#define BOOST_COMPILER_BELOW_VERSION(compiler,version) \ ((compiler != 0) && (compiler < version))
#define BOOST_COMPILER_UP_TO_VERSION(compiler,vesionr) \ ((compiler != 0) && (compiler <= version))
#define BOOST_COMPILER_FROM_TO_VERSION(compiler,min_version,max_version) \ ((compiler != 0) && ((compiler >= min_version) && (compiler <= max_version)))
Example:
#if BOOST_COMPILER_BELOW_VERSION(BOOST_MSVC,1400) ... #endif
No, you have missed my entire point. I want a specific compiler version, by a name which everybody knows, ie. VC71, BCB6 etc., to be associated with the preprocessor tags which the compiler vendor uses to specify that version of the compiler, ie. MSC_VER, __BORLANDC__, in such a way that the code in Boost which provides workarounds or specific code for a given compiler, actually refers to a macro which easily identities that compiler. Your macros above just duplicate the difficulty which already exists in Boost in identifying a well-known name for a compiler/version with the preprocessor macro used in Boost to identify it.

Edward Diener wrote:
Tobias Schwinger wrote:
Edward Diener wrote:
It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as:
#define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER)
where SOME_COMPILER might be VC71,GCC40 etc.
Then in code one could see:
#if defined(BOOST_COMPILER_VC71) etc.
rather than the less understandable
#if defined(MSC_VER == nnnn) etc.
I would just like to see more readability in the Boost code regarding compiler workarounds. I am also aware their is a workaround macro, but even that deals in compiler preprocessor tags rather than a more readable compiler version. I am aware that many workarounds have to deal with versions before or after a certain version number but even that can be made more readable by macros which tell one the actual compiler which is involved.
I realize I am just a reader of Boost code and not a Boost developer but I think this suggestion would make for a little more readable code in its own small way.
How about these?
#define BOOST_COMPILER_WITH_VERSION(compiler,version) \ (compiler == version)
#define BOOST_COMPILER_ABOVE_VERSION(compiler,version) \ (compiler > version)
#define BOOST_COMPILER_FROM_VERSION(compiler,version) \ (compiler >= version)
#define BOOST_COMPILER_BELOW_VERSION(compiler,version) \ ((compiler != 0) && (compiler < version))
#define BOOST_COMPILER_UP_TO_VERSION(compiler,vesionr) \ ((compiler != 0) && (compiler <= version))
#define BOOST_COMPILER_FROM_TO_VERSION(compiler,min_version,max_version) \ ((compiler != 0) && ((compiler >= min_version) && (compiler <= max_version)))
Example:
#if BOOST_COMPILER_BELOW_VERSION(BOOST_MSVC,1400) ... #endif
No, you have missed my entire point. I want a specific compiler version, by a name which everybody knows, ie. VC71, BCB6 etc., to be associated with the preprocessor tags which the compiler vendor uses to specify that version of the compiler, ie. MSC_VER, __BORLANDC__, in such a way that the code in Boost which provides workarounds or specific code for a given compiler, actually refers to a macro which easily identities that compiler. Your macros above just duplicate the difficulty which already exists in Boost in identifying a well-known name for a compiler/version with the preprocessor macro used in Boost to identify it.
Either way, it's the minimal set of comparison operations, IMO. Per-compiler for your proposal then.

Tobias Schwinger <tschwinger@neoscientists.org> writes:
How about these?
#define BOOST_COMPILER_WITH_VERSION(compiler,version) \ (compiler == version)
#define BOOST_COMPILER_ABOVE_VERSION(compiler,version) \ (compiler > version)
#define BOOST_COMPILER_FROM_VERSION(compiler,version) \ (compiler >= version)
#define BOOST_COMPILER_BELOW_VERSION(compiler,version) \ ((compiler != 0) && (compiler < version))
#define BOOST_COMPILER_UP_TO_VERSION(compiler,vesionr) \ ((compiler != 0) && (compiler <= version))
#define BOOST_COMPILER_FROM_TO_VERSION(compiler,min_version,max_version) \ ((compiler != 0) && ((compiler >= min_version) && (compiler <= max_version)))
No. That's what BOOST_WORKAROUND does, and BOOST_WORKAROUND does it better. Please read http://www.boost-consulting.com/boost/boost/detail/workaround.hpp -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Tobias Schwinger <tschwinger@neoscientists.org> writes:
How about these?
#define BOOST_COMPILER_WITH_VERSION(compiler,version) \ (compiler == version)
#define BOOST_COMPILER_ABOVE_VERSION(compiler,version) \ (compiler > version)
#define BOOST_COMPILER_FROM_VERSION(compiler,version) \ (compiler >= version)
#define BOOST_COMPILER_BELOW_VERSION(compiler,version) \ ((compiler != 0) && (compiler < version))
#define BOOST_COMPILER_UP_TO_VERSION(compiler,version) \ ((compiler != 0) && (compiler <= version))
#define BOOST_COMPILER_FROM_TO_VERSION(compiler,min_version,max_version) \ ((compiler != 0) && ((compiler >= min_version) && (compiler <= max_version)))
No. That's what BOOST_WORKAROUND does, and BOOST_WORKAROUND does it better. Please read http://www.boost-consulting.com/boost/boost/detail/workaround.hpp
Know it already. Personally I'm not too much into the stuff I posted either. But the code shows a reasonable set of comparison operations if we encode them in the macro name. We might as well (which seems even better to me) take the comparison operator as part of the macro argument like BOOST_WORKAROUND does: #define BOOST_MSVC_VERSION(test) (defined(BOOST_MSVC) && (BOOST_MSVC test)) And while we're at it -- I'ld like a variant of BOOST_TESTED_AT, "BOOST_TESTED" that also takes the comparison operator: BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED(> 1200)) Thanks, Tobias

Tobias Schwinger <tschwinger@neoscientists.org> writes:
David Abrahams wrote:
Tobias Schwinger <tschwinger@neoscientists.org> writes:
How about these?
#define BOOST_COMPILER_WITH_VERSION(compiler,version) \ (compiler == version)
#define BOOST_COMPILER_ABOVE_VERSION(compiler,version) \ (compiler > version)
<snip>
No. That's what BOOST_WORKAROUND does, and BOOST_WORKAROUND does it better. Please read http://www.boost-consulting.com/boost/boost/detail/workaround.hpp
Know it already. Personally I'm not too much into the stuff I posted either. But the code shows a reasonable set of comparison operations if we encode them in the macro name.
Why should we do that when we can just write the comparison operator with BOOST_WORKAROUND?
We might as well (which seems even better to me) take the comparison operator as part of the macro argument like BOOST_WORKAROUND does:
#define BOOST_MSVC_VERSION(test) (defined(BOOST_MSVC) && (BOOST_MSVC test))
That's not legal code. What are you trying to accomplish that BOOST_WORKAROUND doesn't already provide?
And while we're at it -- I'ld like a variant of BOOST_TESTED_AT, "BOOST_TESTED" that also takes the comparison operator:
BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED(> 1200))
And what do you think that is supposed to do? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Tobias Schwinger <tschwinger@neoscientists.org> writes:
David Abrahams wrote:
Tobias Schwinger <tschwinger@neoscientists.org> writes:
How about these?
#define BOOST_COMPILER_WITH_VERSION(compiler,version) \ (compiler == version)
#define BOOST_COMPILER_ABOVE_VERSION(compiler,version) \ (compiler > version)
<snip>
No. That's what BOOST_WORKAROUND does, and BOOST_WORKAROUND does it better. Please read http://www.boost-consulting.com/boost/boost/detail/workaround.hpp
Know it already. Personally I'm not too much into the stuff I posted either. But the code shows a reasonable set of comparison operations if we encode them in the macro name.
Why should we do that when we can just write the comparison operator with BOOST_WORKAROUND?
No idea, it was part of Edward's proposal.
We might as well (which seems even better to me) take the comparison operator as part of the macro argument like BOOST_WORKAROUND does:
#define BOOST_MSVC_VERSION(test) (defined(BOOST_MSVC) && (BOOST_MSVC test))
That's not legal code. What are you trying to accomplish that BOOST_WORKAROUND doesn't already provide?
Right. s/defined(BOOST_MSVC)/(BOOST_MSVC != 0)/
And while we're at it -- I'ld like a variant of BOOST_TESTED_AT, "BOOST_TESTED" that also takes the comparison operator:
BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED(> 1200))
And what do you think that is supposed to do?
Evaluate to true if we use MSVC and the compiler version is above 1200. That is, with the ability to detect incomplete workarounds (like BOOST_TESTED_AT). It further allows us more flexibility to express what was tested and what wasn't when submitting patches. Regards, Tobias

Tobias Schwinger <tschwinger@neoscientists.org> writes:
And while we're at it -- I'ld like a variant of BOOST_TESTED_AT, "BOOST_TESTED" that also takes the comparison operator:
BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED(> 1200))
And what do you think that is supposed to do?
Evaluate to true if we use MSVC and the compiler version is above 1200.
Ooo kaaay...
That is, with the ability to detect incomplete workarounds (like BOOST_TESTED_AT).
So, can you spell out what that means? When I define BOOST_DETECT_OUTDATED_WORKAROUNDS, what would the behavior be?
It further allows us more flexibility to express what was tested and what wasn't when submitting patches.
That's what BOOST_WORKAROUND does already. I don't see what new information you get from wrapping BOOST_TESTED around the test. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
So, can you spell out what that means? When I define BOOST_DETECT_OUTDATED_WORKAROUNDS, what would the behavior be?
Warn if the same compiler is in use and BOOST_TESTED does not match. On second thought the proposed interface is still too complicated and not exactly perfect yet. However, I'll try to explain why I think that something in this direction could be quite useful: The current BOOST_TESTED_AT assumes that a higher version number of a compiler implies a later release date or integration with Boost. Looking at e.g. VisualC-embedded or Borland BuilderX/Kylix it isn't necessarily the case. Further, patch submitters often have more than one version of a particular compiler around so we could allow to express that a workaround has e.g. been tested with version two and three and version three does not require the workaround. If BOOST_DETECT_UNTESTED_WORKAROUNDS is defined we would get a warning for compiler versions that have not been explicitly marked as tested. So if Boost is ported to a new version of a compiler we'll see all the workarounds in question, regardless whether the version number is the highest around. For regression testing (and the officially supported compilers respectively) we'ld always want to define that macro so insufficient testing of a fresh patch shows up in the regression summary. Regards, Tobias

Tobias Schwinger <tschwinger@neoscientists.org> writes:
David Abrahams wrote:
So, can you spell out what that means? When I define BOOST_DETECT_OUTDATED_WORKAROUNDS, what would the behavior be?
Warn if the same compiler is in use
Same as what?
and BOOST_TESTED does not match.
Match what? What could possibly match BOOST_TESTED?
On second thought the proposed interface is still too complicated and not exactly perfect yet. However, I'll try to explain why I think that something in this direction could be quite useful:
The current BOOST_TESTED_AT assumes that a higher version number of a compiler implies a later release date or integration with Boost.
No, it assumes a higher version number implies a more advanced version of the compiler frontend.
Looking at e.g. VisualC-embedded or Borland BuilderX/Kylix it isn't necessarily the case.
I don't think that matters.
Further, patch submitters often have more than one version of a particular compiler around so we could allow to express that a workaround has e.g. been tested with version two and three and version three does not require the workaround.
THe way you do that is: BOOST_WORKAROUND(SOME_PP_SYMBOL, < 3)
If BOOST_DETECT_UNTESTED_WORKAROUNDS is defined we would get a warning for compiler versions that have not been explicitly marked as tested.
Do you know how to portably generate a warning with the preprocessor?
So if Boost is ported to a new version of a compiler we'll see all the workarounds in question, regardless whether the version number is the highest around. For regression testing (and the officially supported compilers respectively) we'ld always want to define that macro so insufficient testing of a fresh patch shows up in the regression summary.
What problem are we currently having that would be solved by this suggestion, even if you could implement it (which I don't believe is possible, at least not the way you've got it currently formulated)? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Tobias Schwinger <tschwinger@neoscientists.org> writes:
Do you know how to portably generate a warning with the preprocessor?
No idea, but if there isn't there is still the option to trigger an error condition instead.
So if Boost is ported to a new version of a compiler we'll see all the workarounds in question, regardless whether the version number is the highest around. For regression testing (and the officially supported compilers respectively) we'ld always want to define that macro so insufficient testing of a fresh patch shows up in the regression summary.
What problem are we currently having that would be solved by this suggestion, even if you could implement it (which I don't believe is possible, at least not the way you've got it currently formulated)?
The thread on making Boost.Regex compile on VisualC-embedded (1) and the latest patch I posted (2) made me to think in this direction: (1) Say we have support for version one and version three, defining BOOST_DETECT_OUTDATED_WORKAROUNDS can't help us for porting/updating to/for version two. (2) I would have liked to express: "The highest version of this compiler I have does not require the workaround the second highest version I have does. I suspect a compiler with a greater version number to need the workaround again, though." However, it's overly important: things work the way they are and I really don't want to waste your time :-). Regards, Tobias

Tobias Schwinger wrote:
David Abrahams wrote:
Tobias Schwinger <tschwinger@neoscientists.org> writes:
Do you know how to portably generate a warning with the preprocessor?
No idea, but if there isn't there is still the option to trigger an error condition instead.
So if Boost is ported to a new version of a compiler we'll see all the workarounds in question, regardless whether the version number is the highest around. For regression testing (and the officially supported compilers respectively) we'ld always want to define that macro so insufficient testing of a fresh patch shows up in the regression summary.
What problem are we currently having that would be solved by this suggestion, even if you could implement it (which I don't believe is possible, at least not the way you've got it currently formulated)?
The thread on making Boost.Regex compile on VisualC-embedded (1) and the latest patch I posted (2) made me to think in this direction:
(1) Say we have support for version one and version three, defining BOOST_DETECT_OUTDATED_WORKAROUNDS can't help us for porting/updating to/for version two.
(2) I would have liked to express: "The highest version of this compiler I have does not require the workaround the second highest version I have does. I suspect a compiler with a greater version number to need the workaround again, though."
However, it's overly important: things work the way they are and I really don't want to waste your time :-).
Hmm... The irony wasn't intended I just forgot to write the "not". Should read "it's not overly important". Regards, Tobias

Tobias Schwinger wrote:
Tobias Schwinger wrote:
However, it's overly important: things work the way they are and I really don't want to waste your time :-).
Hmm... The irony wasn't intended I just forgot to write the "not". Should read "it's not overly important".
Follow Boost Discussian policy please. Don't quote pieces you don't need. List volume is very high, and it's really hard, so skipping irrelevant text takes a lot of time. Andrey

http://www.boost-consulting.com/boost/boost/detail/workaround.hpp
Reading this, I see a comment on line 42ff which seems to have suffered bitrot. The markers that refer to the line above don't seem to refer to anything particular. It probably wanted to refer to the additional set around (symbol test), but I'm not sure. Uli

Ulrich Eckhardt <uli@doommachine.dyndns.org> writes:
http://www.boost-consulting.com/boost/boost/detail/workaround.hpp
Reading this, I see a comment on line 42ff which seems to have suffered bitrot. The markers that refer to the line above don't seem to refer to anything particular. It probably wanted to refer to the additional set around (symbol test), but I'm not sure.
Looks perfect to me. Are you working a fixed-width font? -- Dave Abrahams Boost Consulting www.boost-consulting.com

Though there may be many details about this, I think the suggestion will be really helpful in improving the readability of the Boost code. Most readers/users of Boost are not familiar with specific compiler versioning details, and with these macros defined and used consistently, It will be extremely easy for readers to recognize those compiler-specific workaround parts in the code, and choose to look into or just ignore them. I also suggest that these macros be a part of the Boost.Config, and all the Boost library authors to utilize them consistently. Furthermore, all the existing code could be rewrite accordingly if possible. Edward Diener wrote:
I think this suggestion would make for a little more readable code in its own small way.

Edward Diener <eddielee@tropicsoft.com> writes:
It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as:
#define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER)
Not sure why you'd want to do that. Then you only get a binary value for BOOST_COMPILER_SOME_COMPILER. I'd rather havea composite version number.
where SOME_COMPILER might be VC71,GCC40 etc.
Then in code one could see:
#if defined(BOOST_COMPILER_VC71) etc.
rather than the less understandable
#if defined(MSC_VER == nnnn) etc.
Actually we have BOOST_MSVC. The only reason we'd test _MSC_VER is for those cases where we want to catch *all* compilers that emulate VC++ (e.g. for #pragma once).
I would just like to see more readability in the Boost code regarding compiler workarounds. I am also aware their is a workaround macro, but even that deals in compiler preprocessor tags rather than a more readable compiler version. I am aware that many workarounds have to deal with versions before or after a certain version number but even that can be made more readable by macros which tell one the actual compiler which is involved.
We've had a plan for a long while to introduce a #define for each compiler vendor. One reason to do that is that many preprocessors have a (often very useful) warning that barks whenever you do a comparison test on a symbol that isn't #defined. The standard says it's legal to test un-defined symbols (they are treated as zero), but that often masks programmer errors. Right now, to avoid the warnings for most symbols, you have to write: #if defined(COMPILER_SYMBOL) && BOOST_WORKAROUND(COMPILER_SYMBOL, whatever) ... #endif Whereas we'd like to simply write #if BOOST_WORKAROUND(COMPILER_SYMBOL, whatever) ... #endif (and many of us already do, which leaves some users with lots of annoying warnings). So we'd like to have a suite of symbols like BOOST_GCC_VERSION, etc., that are always #defined, and are zero if the compiler in question isn't being used.
I realize I am just a reader of Boost code and not a Boost developer but I think this suggestion would make for a little more readable code in its own small way.
I agree! I suggest you prepare a patch for the config library that we can use in Boost after 1.33.0 -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as:
#define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER)
Not sure why you'd want to do that. Then you only get a binary value for BOOST_COMPILER_SOME_COMPILER.
You would get a boolean of true or false.
I'd rather havea composite version number.
I would rather know whether some compiler is being referred to or not.
where SOME_COMPILER might be VC71,GCC40 etc.
Then in code one could see:
#if defined(BOOST_COMPILER_VC71) etc.
rather than the less understandable
#if defined(MSC_VER == nnnn) etc.
Actually we have BOOST_MSVC. The only reason we'd test _MSC_VER is for those cases where we want to catch *all* compilers that emulate VC++ (e.g. for #pragma once).
Does BOOST_MSVC referring to all versions of MSVC ? I wanted something easy which refers to particular major version of particular compiler toward which Boost is targeted.
I would just like to see more readability in the Boost code regarding compiler workarounds. I am also aware their is a workaround macro, but even that deals in compiler preprocessor tags rather than a more readable compiler version. I am aware that many workarounds have to deal with versions before or after a certain version number but even that can be made more readable by macros which tell one the actual compiler which is involved.
We've had a plan for a long while to introduce a #define for each compiler vendor. One reason to do that is that many preprocessors have a (often very useful) warning that barks whenever you do a comparison test on a symbol that isn't #defined. The standard says it's legal to test un-defined symbols (they are treated as zero), but that often masks programmer errors. Right now, to avoid the warnings for most symbols, you have to write:
#if defined(COMPILER_SYMBOL) && BOOST_WORKAROUND(COMPILER_SYMBOL, whatever) ... #endif
Whereas we'd like to simply write
#if BOOST_WORKAROUND(COMPILER_SYMBOL, whatever) ... #endif
(and many of us already do, which leaves some users with lots of annoying warnings).
So we'd like to have a suite of symbols like BOOST_GCC_VERSION, etc., that are always #defined, and are zero if the compiler in question isn't being used.
Is there a list of general compiler/versions which Boost supports. On Windows I know of Visual C++ 6.0, 7.0, 7.1, and 8.0, and Borland BCB5 and BCB6. I am not sure of which _MSC_VER corresponds to each of the compilers although I can test it out for ther ones I have on my machine. Is there a comprehensive list kept anywhere.
I realize I am just a reader of Boost code and not a Boost developer but I think this suggestion would make for a little more readable code in its own small way.
I agree! I suggest you prepare a patch for the config library that we can use in Boost after 1.33.0
If I can get a comprehensive list of compiler/versions and their corresponding preprocessor symbols I will be glad to do it. I can find out the appropriate information for Microsoft and Borland on Windows easily enough myself.

Edward Diener <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as:
#define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER)
Not sure why you'd want to do that. Then you only get a binary value for BOOST_COMPILER_SOME_COMPILER.
You would get a boolean of true or false.
That wouldn't be very useful in Boost. If you look through Boost code you'll find a lot of places where a <, <=,>, or >= comparison is needed against a compiler version.
I'd rather have a composite version number.
I would rather know whether some compiler is being referred to or not.
Then learn what the version numbers mean?
#if defined(BOOST_COMPILER_VC71) etc.
rather than the less understandable
#if defined(MSC_VER == nnnn) etc.
Actually we have BOOST_MSVC. The only reason we'd test _MSC_VER is for those cases where we want to catch *all* compilers that emulate VC++ (e.g. for #pragma once).
Does BOOST_MSVC referring to all versions of MSVC ?
Yes.
I wanted something easy which refers to particular major version of particular compiler toward which Boost is targeted.
I guess you'd have to make it up yourself, because if we used that in Boost it would become a big(ger) mess.
Is there a list of general compiler/versions which Boost supports.
No
I realize I am just a reader of Boost code and not a Boost developer but I think this suggestion would make for a little more readable code in its own small way.
I agree! I suggest you prepare a patch for the config library that we can use in Boost after 1.33.0
If I can get a comprehensive list of compiler/versions and their corresponding preprocessor symbols I will be glad to do it. I can find out the appropriate information for Microsoft and Borland on Windows easily enough myself.
Well, I think I spoke too soon. What you appear to be asking for would add little of value to Boost and would undermine the capabilities we get from BOOST_WORKAROUND. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as:
#define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER)
Not sure why you'd want to do that. Then you only get a binary value for BOOST_COMPILER_SOME_COMPILER.
You would get a boolean of true or false.
That wouldn't be very useful in Boost. If you look through Boost code you'll find a lot of places where a <, <=,>, or >= comparison is needed against a compiler version.
The way I have set it up, for example, is to use #define BOOST_COMPILER_VC6 (...) #define BOOST_COMPILER_VC6_OR_LOWER (...) #define BOOST_COMPILER_VC6_OR_HIGHER (...) ( along with th same for VC7, VC71, and VC8 ) You could write: #if BOOST_COMPILER_VC6 // code #endif or #if BOOST_COMPILER_VC6_OR_HIGHER (...) // code #endif or even #if BOOST_COMPILER_VC6 || BOOST_COMPILER_VC7 // code #endif You can imagine the ease of any combinations you like. Of course if one would rather see: #if (BOOST_MSVC >= 1310) // code #endif or #if BOOST_WORKAROUND(BOOST_MSVC,>= 1310)+ // code #endif because that is better, then why should I suggest otherwise ?
I'd rather have a composite version number.
I would rather know whether some compiler is being referred to or not.
Then learn what the version numbers mean?
Specifying a compiler version via a macro makes the code much clearer. This does not keep anyone from using BOOST_MSVC if they like or even combining it with the compiler identiification macros shown above.
#if defined(BOOST_COMPILER_VC71) etc.
rather than the less understandable
#if defined(MSC_VER == nnnn) etc.
Actually we have BOOST_MSVC. The only reason we'd test _MSC_VER is for those cases where we want to catch *all* compilers that emulate VC++ (e.g. for #pragma once).
Ok, Makes sense.
Does BOOST_MSVC referring to all versions of MSVC ?
Yes.
I wanted something easy which refers to particular major version of particular compiler toward which Boost is targeted.
I guess you'd have to make it up yourself, because if we used that in Boost it would become a big(ger) mess.
I definitely don't want to make a mess.
Is there a list of general compiler/versions which Boost supports.
No
I realize I am just a reader of Boost code and not a Boost developer but I think this suggestion would make for a little more readable code in its own small way.
I agree! I suggest you prepare a patch for the config library that we can use in Boost after 1.33.0
If I can get a comprehensive list of compiler/versions and their corresponding preprocessor symbols I will be glad to do it. I can find out the appropriate information for Microsoft and Borland on Windows easily enough myself.
Well, I think I spoke too soon. What you appear to be asking for would add little of value to Boost and would undermine the capabilities we get from BOOST_WORKAROUND.
I would never want to "undermine" Boost code in any way.

Edward Diener <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as:
#define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER)
Not sure why you'd want to do that. Then you only get a binary value for BOOST_COMPILER_SOME_COMPILER.
You would get a boolean of true or false.
That wouldn't be very useful in Boost. If you look through Boost code you'll find a lot of places where a <, <=,>, or >= comparison is needed against a compiler version.
The way I have set it up, for example, is to use
#define BOOST_COMPILER_VC6 (...) #define BOOST_COMPILER_VC6_OR_LOWER (...) #define BOOST_COMPILER_VC6_OR_HIGHER (...)
That would be nasty for a compiler such as GCC. Go take a look at the releases page.
( along with th same for VC7, VC71, and VC8 )
You could write:
#if BOOST_COMPILER_VC6 // code #endif
or
#if BOOST_COMPILER_VC6_OR_HIGHER (...) // code #endif
or even
#if BOOST_COMPILER_VC6 || BOOST_COMPILER_VC7 // code #endif
You can imagine the ease of any combinations you like.
Of course if one would rather see:
#if (BOOST_MSVC >= 1310) // code #endif
or
#if BOOST_WORKAROUND(BOOST_MSVC,>= 1310)+ // code #endif
because that is better, then why should I suggest otherwise ?
I don't know. It doesn't only have to do with what I'd rather see, but with the functionality provided by BOOST_WORKAROUND. Have you read the entire comment there?
I'd rather have a composite version number.
I would rather know whether some compiler is being referred to or not.
Then learn what the version numbers mean?
Specifying a compiler version via a macro makes the code much clearer. This does not keep anyone from using BOOST_MSVC if they like or even combining it with the compiler identiification macros shown above.
I'd rather have one consistent way to do these tests than have a giant suite of testing macros for every compiler and version.
Well, I think I spoke too soon. What you appear to be asking for would add little of value to Boost and would undermine the capabilities we get from BOOST_WORKAROUND.
I would never want to "undermine" Boost code in any way.
Maybe that wasn't the best choice of words. I just meant that we'd lose the functionality provided by BOOST_WORKAROUND if we started using the macros you suggest instead. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
It would be much easier, and less confusing, when looking at compiler workarounds in Boost code if their were defines for various compilers/versions in a configuratiion header file such as:
#define BOOST_COMPILER_SOME_COMPILER_LOWER (PREPROCESSOR_TAG >= nnnn) #define BOOST_COMPILER_SOME_COMPILER_UPPER (PREPROCESSOR_TAG <= nnnn) #define BOOST_COMPILER_SOME_COMPILER (BOOST_COMPILER_SOME_COMPILER_LOWER && BOOST_COMPILER_SOME_COMPILER_UPPER)
Not sure why you'd want to do that. Then you only get a binary value for BOOST_COMPILER_SOME_COMPILER.
You would get a boolean of true or false.
That wouldn't be very useful in Boost. If you look through Boost code you'll find a lot of places where a <, <=,>, or >= comparison is needed against a compiler version.
The way I have set it up, for example, is to use
#define BOOST_COMPILER_VC6 (...) #define BOOST_COMPILER_VC6_OR_LOWER (...) #define BOOST_COMPILER_VC6_OR_HIGHER (...)
That would be nasty for a compiler such as GCC. Go take a look at the releases page.
I agree. There are some compilers, like GCC, in which there is more rarely a distinct version, meaning major and minor version numbers. But there are many compilers which work with that sort of release scheme, such as Microsoft, Borland, Intel, CodeWarrior, Comeau etc. GCC is the oddity which puts out slightly changed releases quite often, because it is free and open source. Most other compilers have specific versions which do not change for a good amount of time.
( along with th same for VC7, VC71, and VC8 )
You could write:
#if BOOST_COMPILER_VC6 // code #endif
or
#if BOOST_COMPILER_VC6_OR_HIGHER (...) // code #endif
or even
#if BOOST_COMPILER_VC6 || BOOST_COMPILER_VC7 // code #endif
You can imagine the ease of any combinations you like.
Of course if one would rather see:
#if (BOOST_MSVC >= 1310) // code #endif
or
#if BOOST_WORKAROUND(BOOST_MSVC,>= 1310)+ // code #endif
because that is better, then why should I suggest otherwise ?
I don't know.
It doesn't only have to do with what I'd rather see, but with the functionality provided by BOOST_WORKAROUND. Have you read the entire comment there?
Yes, I have. BOOST_WORKAROUND is of course more flexible. What I wanted to offer was a set of macros, for compilers supporting distinct versions which stay the same for a fairly long time, so that the workaround code could be more readable. That's all really. I realize that with BOOST_WORKAROUND one can add a comment saying to what each workaround actually refers, but this is often not done. Furthermore I see quite a bit of code, whether rightly or wrongly, which does not use BOOST_WORKAROUND. My solution, if you are interested, also allowed a still released distinct version macro for a compiler to be easily changed if the version encompassed a range of preprocessor macro values, so that, as an example, if VC8 SP1 comes out and _MSC_VER changes for it to 1410, a single change in a single file updates the appropriate macros. Of course it is trivial to do that...
I'd rather have a composite version number.
I would rather know whether some compiler is being referred to or not.
Then learn what the version numbers mean?
Specifying a compiler version via a macro makes the code much clearer. This does not keep anyone from using BOOST_MSVC if they like or even combining it with the compiler identiification macros shown above.
I'd rather have one consistent way to do these tests than have a giant suite of testing macros for every compiler and version.
Well, I think I spoke too soon. What you appear to be asking for would add little of value to Boost and would undermine the capabilities we get from BOOST_WORKAROUND.
I would never want to "undermine" Boost code in any way.
Maybe that wasn't the best choice of words. I just meant that we'd lose the functionality provided by BOOST_WORKAROUND if we started using the macros you suggest instead.
We would not so much as lose the functionality as offer a more simplistic and readable way to express it. My suggestion is just about readability. When I see: #if BOOST_WORKAROUND(nnnn,comparison operator) I often can not tell to what it refers without some comment. But if I saw, as an example: #if BOOST_COMPILER_VC71 it becomes easier to understand. Anyway if Boost developers are happy with understanding workarounds by only using preprocessor symbols in comparisons, whether using BOOST_WORKAROUND or otherwise, I do not want to change things. And you are right in that adding a set of new macros, although all would start with BOOST_COMPILER_, might be overkill. I like syntactic sugar if it produces greater readability and the cost is very small. I just found all the proprocessor macro version number references in BOOST_WORKAROUND and bare #if statements annoying. I thought the code would be much easier to read if the #if statement referred to distinct compiler versions. Even GCC does put out general versions which could be tagged in such a way as to make the reading of the code more understandable. I also think Boost should have somewhere a document or table which relates each distinct version of a compiler to a range of the appropriate preprocessor version numbers. If one has the compiler on one's machine, I believe the config.cpp test will tell that, but if one does not have the compiler it is impossible to tell.

Edward Diener <eddielee@tropicsoft.com> writes:
Maybe that wasn't the best choice of words. I just meant that we'd lose the functionality provided by BOOST_WORKAROUND if we started using the macros you suggest instead.
We would not so much as lose the functionality as offer a more simplistic and readable way to express it. My suggestion is just about readability. When I see:
#if BOOST_WORKAROUND(nnnn,comparison operator)
I often can not tell to what it refers without some comment. But if I saw, as an example:
#if BOOST_COMPILER_VC71
it becomes easier to understand.
You obviously didn't read the entire comment in workaround.hpp then. #if BOOST_COMPILER_VC71 can't support BOOST_DETECT_OUTDATED_WORKAROUNDS. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
Maybe that wasn't the best choice of words. I just meant that we'd lose the functionality provided by BOOST_WORKAROUND if we started using the macros you suggest instead.
We would not so much as lose the functionality as offer a more simplistic and readable way to express it. My suggestion is just about readability. When I see:
#if BOOST_WORKAROUND(nnnn,comparison operator)
I often can not tell to what it refers without some comment. But if I saw, as an example:
#if BOOST_COMPILER_VC71
it becomes easier to understand.
You obviously didn't read the entire comment in workaround.hpp then. #if BOOST_COMPILER_VC71 can't support BOOST_DETECT_OUTDATED_WORKAROUNDS.
You mean the BOOST_TESTED_AT syntax ? No, it does not support that. However one could create a series of macros, let us say for VC71, like this: // These are always defined and included in a header file at the top of select_compiler_config.hpp #define BOOST_COMPILER_VC _MSC_VER #define BOOST_COMPILER_VC71_VERSION (1310) #define BOOST_COMPILER_VC71_VERSION_HIGH (1310) // This would be different for a later service pack of VC71 which had a higher _MSC_VER, and is the only define that might ever need to be changed for this compiler/version // These are defined as 0 unless the Microsoft compiler header is selected in which case the definitions below are in a header file at the top of visualc.hpp #define BOOST_COMPILER_VC71_OR_HIGHER (BOOST_COMPILER_VC >= BOOST_COMPILER_VC71_VERSION) #define BOOST_COMPILER_VC71_OR_LOWER (BOOST_COMPILER_VC <= BOOST_COMPILER_VC71_VERSION_HIGH) #define BOOST_COMPILER_VC71 (BOOST_COMPILER_VC71_OR_HIGHER && BOOST_COMPILER_VC71_OR_LOWER) You could now say: #if BOOST_WORKAROUND(BOOST_COMPILER_VC,BOOST_COMPILER_VC71_VERSION) // code #endif or, in a different situation: #if BOOST_WORKAROUND(BOOST_COMPILER_VC,BOOST_TESTED_AT(BOOST_COMPILER_VC71_VERSION_HIGH)) // code #endif or, in a different situation: #if BOOST_COMPILER_VC71 // and any other combinations you like // code #endif etc. If you are arguing for only using BOOST_WORKAROUND, and never using a construct like the last one, then you are advocating always using specific version numbers. In that case you may want to consider at least forms like BOOST_COMPILER_VC71_VERSION and BOOST_COMPILER_VC71_VERSION_HIGH useful for your BOOST_WORKAROUND and BOOST_TESTED_AT macros. Of course you would have the same macros for each compiler/version, as an example with BORLAND instead of VC, __BORLANDC__ instead of _MSC_VER. and BCB6 instead of VC71. I am sure you get the idea. For BCB6 it would like like this: // These are always defined and included in a header file at the top of select_compiler_config.hpp #define BOOST_COMPILER_BORLAND __BORLANDC__ #define BOOST_COMPILER_BCB6_VERSION (0x560) #define BOOST_COMPILER_BCB6_VERSION_HIGH (0x564) // this is the only define that might ever need to be changed for this compiler/version // These are defined as 0 unless the Borland compiler header is selected in which case the definitions below are in a header file at the top of borland.hpp #define BOOST_COMPILER_BCB6_OR_HIGHER (BOOST_COMPILER_BORLAND >= BOOST_COMPILER_BCB6_VERSION) #define BOOST_COMPILER_BCB6_OR_LOWER (BOOST_COMPILER_BORLAND <= BOOST_COMPILER_BCB6_VERSION_HIGH) #define BOOST_COMPILER_BCB6 (BOOST_COMPILER_BCB6_OR_HIGHER && BOOST_COMPILER_BCB6_OR_LOWER) You could now say: #if BOOST_WORKAROUND(BOOST_COMPILER_BORLAND,BOOST_COMPILER_BCB6_VERSION) // code #endif or, in a different situation: #if BOOST_WORKAROUND(BOOST_COMPILER_BORLAND,BOOST_TESTED_AT(BOOST_COMPILER_BCB6_VERSION_HIGH)) // code #endif or, in a different situation: #if BOOST_COMPILER_BCB6 // and any other combinations you like // code #endif etc. All of this is syntactic sugar so that the BOOST_WORKAROUND, BOOST_TESTED_AT, or the raw #if versiontag op nnnn, is more readable.

Edward Diener <eddielee@tropicsoft.com> writes:
You obviously didn't read the entire comment in workaround.hpp then. #if BOOST_COMPILER_VC71 can't support BOOST_DETECT_OUTDATED_WORKAROUNDS.
You mean the BOOST_TESTED_AT syntax ? No, it does not support that.
No, I mean the *functionality*. I don't care that much about the syntax. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Edward Diener <eddielee@tropicsoft.com> writes:
one could create a series of macros, let us say for VC71, like this:
// These are always defined and included in a header file at the top of select_compiler_config.hpp
#define BOOST_COMPILER_VC _MSC_VER
It's a lot more complicated than that, unfortunately, because many other compilers define _MSC_VER to "act compatible" with VC++.
You could now say:
#if BOOST_WORKAROUND(BOOST_COMPILER_VC,BOOST_COMPILER_VC71_VERSION) // code #endif
or, in a different situation:
#if BOOST_WORKAROUND(BOOST_COMPILER_VC,BOOST_TESTED_AT(BOOST_COMPILER_VC71_VERSION_HIGH)) // code #endif
or, in a different situation:
#if BOOST_COMPILER_VC71 // and any other combinations you like // code #endif
Okay, I understand what you're driving at. I'm not sure if going down this road is worth the trouble, but if it is, I'd rather see a standard system for referring to versions numerically. So, for example: Version Value ------- ----- 6.0 060000 6.0sp5 060005 7.0 070000 7.1 070100 5.3.4 050304 3.4.3 030403 2.95.3 029503 I don't particularly think BOOST_COMPILER_VC == BOOST_COMPILER_VC71_VERSION is more expressive than BOOST_MSVC_VERSION == 070100 Nor do I think BOOST_COMPILER_VC <= BOOST_COMPILER_VC71_VERSION_HIGH is an improvement over BOOST_MSVC_VERSION < 070200
If you are arguing for only using BOOST_WORKAROUND, and never using a construct like the last one
Among other things, I am.
then you are advocating always using specific version numbers.
I don't know what you mean.
In that case you may want to consider at least forms like BOOST_COMPILER_VC71_VERSION and BOOST_COMPILER_VC71_VERSION_HIGH useful for your BOOST_WORKAROUND and BOOST_TESTED_AT macros.
I understand why you want it, but am not fond of your proposed names and syntax.
Of course you would have the same macros for each compiler/version
As I'm sure you know, I do think there should be a separate macro for each compiler, explicitly #defined to 0 when that compiler is not in use. -- Dave Abrahams Boost Consulting www.boost-consulting.com

From: David Abrahams <dave@boost-consulting.com>
Edward Diener <eddielee@tropicsoft.com> writes:
Okay, I understand what you're driving at. I'm not sure if going down this road is worth the trouble, but if it is, I'd rather see a standard system for referring to versions numerically. So, for example:
Version Value ------- ----- 6.0 060000 6.0sp5 060005 7.0 070000 7.1 070100 5.3.4 050304 3.4.3 030403 2.95.3 029503
You probably need to allow another digit for each field. 95 is awfully close to rolling over to three digits.
I don't particularly think
BOOST_COMPILER_VC == BOOST_COMPILER_VC71_VERSION
is more expressive than
BOOST_MSVC_VERSION == 070100
Given a fixed numbering system, the latter is more readable.
Nor do I think
BOOST_COMPILER_VC <= BOOST_COMPILER_VC71_VERSION_HIGH
is an improvement over
BOOST_MSVC_VERSION < 070200
Given a fixed numbering system, the latter is more readable.
In that case you may want to consider at least forms like BOOST_COMPILER_VC71_VERSION and BOOST_COMPILER_VC71_VERSION_HIGH useful for your BOOST_WORKAROUND and BOOST_TESTED_AT macros.
I understand why you want it, but am not fond of your proposed names and syntax.
I like the fixed numbering system, though. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

On Tue, Jul 12, 2005 at 10:55:37AM -0400, Rob Stewart wrote:
From: David Abrahams <dave@boost-consulting.com>
Edward Diener <eddielee@tropicsoft.com> writes:
Okay, I understand what you're driving at. I'm not sure if going down this road is worth the trouble, but if it is, I'd rather see a standard system for referring to versions numerically. So, for example:
Version Value ------- ----- 6.0 060000 6.0sp5 060005 7.0 070000 7.1 070100 5.3.4 050304 3.4.3 030403 2.95.3 029503
You probably need to allow another digit for each field. 95 is awfully close to rolling over to three digits.
I think that's why it was chosen, and it's VERY unlikely there'll be any more GCC 2.x releases. RedHat shipped a modified GCC with version number 2.96, but I'll bet bread there won't be a 2.100 So if GCC 2.95 is the only version number close to 3 digits, I don't think you need to worry about running out of digits. jon

From: Jonathan Wakely <cow@compsoc.man.ac.uk>
On Tue, Jul 12, 2005 at 10:55:37AM -0400, Rob Stewart wrote:
From: David Abrahams <dave@boost-consulting.com>
Edward Diener <eddielee@tropicsoft.com> writes:
standard system for referring to versions numerically. So, for example:
Version Value ------- ----- 6.0 060000 6.0sp5 060005 7.0 070000 7.1 070100 5.3.4 050304 3.4.3 030403 2.95.3 029503
You probably need to allow another digit for each field. 95 is awfully close to rolling over to three digits.
I think that's why it was chosen, and it's VERY unlikely there'll be any more GCC 2.x releases. RedHat shipped a modified GCC with version number 2.96, but I'll bet bread there won't be a 2.100
So if GCC 2.95 is the only version number close to 3 digits, I don't think you need to worry about running out of digits.
What's to stop any compiler from using a 3 digit version number sometime in the future? Yes, GCC has moved on to 4.x, so there's no 3.x version even close to that, and there aren't likely to be (m)any more 2.x releases, but if you are going to choose a convention, it ought to account for forseeable problems, right? -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart wrote:
From: Jonathan Wakely
I think that's why it was chosen, and it's VERY unlikely there'll be any more GCC 2.x releases. RedHat shipped a modified GCC with version number 2.96, but I'll bet bread there won't be a 2.100
So if GCC 2.95 is the only version number close to 3 digits, I don't think you need to worry about running out of digits.
What's to stop any compiler from using a 3 digit version number sometime in the future? Yes, GCC has moved on to 4.x, so there's no 3.x version even close to that, and there aren't likely to be (m)any more 2.x releases, but if you are going to choose a convention, it ought to account for forseeable problems, right?
The ability to accommodate these unlikely scenarios has to be balanced against usability. If a test for GCC with major version < 3 has to use "3000000," chances are good that a test will be misspelled and a needed workaround will not be applied. Jonathan

Jonathan Turkanis wrote:
The ability to accommodate these unlikely scenarios has to be balanced against usability. If a test for GCC with major version < 3 has to use "3000000," chances are good that a test will be misspelled and a needed workaround will not be applied.
It is possible to put an expression to calculate the 3000000 in this case into a macro: #define BOOST_VERSION(major,minor,patchlvl) \ (major * 1000000 + minor * 1000 + patchlvl) #define BOOST_GCC \ BOOST_GCC_VERSION(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) Example: #if BOOST_WORKAROUND(BOOST_GCC,< BOOST_VERSION(3,2,3)) // ... #endif Regards, Tobias

Tobias Schwinger <tschwinger@neoscientists.org> writes:
Jonathan Turkanis wrote:
The ability to accommodate these unlikely scenarios has to be balanced against usability. If a test for GCC with major version < 3 has to use "3000000," chances are good that a test will be misspelled and a needed workaround will not be applied.
It is possible to put an expression to calculate the 3000000 in this case into a macro:
#define BOOST_VERSION(major,minor,patchlvl) \ (major * 1000000 + minor * 1000 + patchlvl)
#define BOOST_GCC \ BOOST_GCC_VERSION(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
Example:
#if BOOST_WORKAROUND(BOOST_GCC,< BOOST_VERSION(3,2,3)) // ... #endif
Or we could arrange to write: #if BOOST_WORKAROUND(BOOST_GCC,< 3,2,3) -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams <dave@boost-consulting.com> writes:
Tobias Schwinger <tschwinger@neoscientists.org> writes:
Jonathan Turkanis wrote:
The ability to accommodate these unlikely scenarios has to be balanced against usability. If a test for GCC with major version < 3 has to use "3000000," chances are good that a test will be misspelled and a needed workaround will not be applied.
It is possible to put an expression to calculate the 3000000 in this case into a macro:
#define BOOST_VERSION(major,minor,patchlvl) \ (major * 1000000 + minor * 1000 + patchlvl)
#define BOOST_GCC \ BOOST_GCC_VERSION(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
Example:
#if BOOST_WORKAROUND(BOOST_GCC,< BOOST_VERSION(3,2,3)) // ... #endif
Or we could arrange to write:
#if BOOST_WORKAROUND(BOOST_GCC,< 3,2,3)
Nobody likes that one? What about: #if BOOST_WORKAROUND(GCC,< 3,2,3) Pretty succinct, I think. I'm not sure about getting BOOST_TESTED_AT to work here. #if BOOST_WORKAROUND(GCC, BOOST_TESTED_AT 3,2,3) would be nice syntax, but I'm just not sure how workable it is. We may end up with #if BOOST_WORKAROUND_TESTED_AT(GCC, 3,2,3) which is actually pretty nice and requires fewer fancy tricks to implement. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
David Abrahams <dave@boost-consulting.com> writes:
Or we could arrange to write:
#if BOOST_WORKAROUND(BOOST_GCC,< 3,2,3)
Nobody likes that one?
What about:
#if BOOST_WORKAROUND(GCC,< 3,2,3)
Pretty succinct, I think.
Are you sure it's legal to take "< 3" and paste on the remaining characters, e.g., "0404"? My knowledge of the preprocesor is pretty limited, but this sounds like something Paul M. told me was undefined.
I'm not sure about getting BOOST_TESTED_AT to work here.
#if BOOST_WORKAROUND(GCC, BOOST_TESTED_AT 3,2,3)
would be nice syntax, but I'm just not sure how workable it is. We may end up with
#if BOOST_WORKAROUND_TESTED_AT(GCC, 3,2,3)
which is actually pretty nice and requires fewer fancy tricks to implement.
You could also do BOOST_WORKADOUND(GCC, LESS(3,2,3)) BOOST_WORKADOUND(GCC, LESS_EQ(3,2,3)) BOOST_WORKADOUND(GCC, TESTED_AT(3,2,3)) ... Jonathan

"Jonathan Turkanis" <technews@kangaroologic.com> writes:
David Abrahams wrote:
David Abrahams <dave@boost-consulting.com> writes:
Or we could arrange to write:
#if BOOST_WORKAROUND(BOOST_GCC,< 3,2,3)
Nobody likes that one?
What about:
#if BOOST_WORKAROUND(GCC,< 3,2,3)
Pretty succinct, I think.
Are you sure it's legal to take "< 3" and paste on the remaining characters, e.g., "0404"? My knowledge of the preprocesor is pretty limited, but this sounds like something Paul M. told me was undefined.
No, I'm not sure. I believe you if you tell me it's undefined. We might need another comma. #if BOOST_WORKAROUND(GCC, <, 3,2,3)
I'm not sure about getting BOOST_TESTED_AT to work here.
#if BOOST_WORKAROUND(GCC, BOOST_TESTED_AT 3,2,3)
would be nice syntax, but I'm just not sure how workable it is. We may end up with
#if BOOST_WORKAROUND_TESTED_AT(GCC, 3,2,3)
which is actually pretty nice and requires fewer fancy tricks to implement.
You could also do
BOOST_WORKADOUND(GCC, LESS(3,2,3)) BOOST_WORKADOUND(GCC, LESS_EQ(3,2,3)) BOOST_WORKADOUND(GCC, TESTED_AT(3,2,3)) ...
Ick; why use a name to stand in for the operator when we can use the operator directly? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Jonathan Turkanis" <technews@kangaroologic.com> writes:
You could also do
BOOST_WORKADOUND(GCC, LESS(3,2,3)) BOOST_WORKADOUND(GCC, LESS_EQ(3,2,3)) BOOST_WORKADOUND(GCC, TESTED_AT(3,2,3)) ...
Ick; why use a name to stand in for the operator when we can use the operator directly?
For uniform treatment of comparisons and TESTED_AT. Maybe there's some other way to do the same thing. Jonathan

"Jonathan Turkanis" <technews@kangaroologic.com> writes:
David Abrahams wrote:
"Jonathan Turkanis" <technews@kangaroologic.com> writes:
You could also do
BOOST_WORKADOUND(GCC, LESS(3,2,3)) BOOST_WORKADOUND(GCC, LESS_EQ(3,2,3)) BOOST_WORKADOUND(GCC, TESTED_AT(3,2,3)) ...
Ick; why use a name to stand in for the operator when we can use the operator directly?
For uniform treatment of comparisons and TESTED_AT. Maybe there's some other way to do the same thing.
I think I like BOOST_WORKAROUND_TESTED_AT(GCC, 3,2,3) myself. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams <dave@boost-consulting.com> writes:
Are you sure it's legal to take "< 3" and paste on the remaining characters, e.g., "0404"? My knowledge of the preprocesor is pretty limited, but this sounds like something Paul M. told me was undefined.
No, I'm not sure. I believe you if you tell me it's undefined. We might need another comma.
Now I don't believe you anymore. See the example at http://www.boost.org/libs/preprocessor/doc/ref/enum_params.html -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
David Abrahams <dave@boost-consulting.com> writes:
Are you sure it's legal to take "< 3" and paste on the remaining characters, e.g., "0404"? My knowledge of the preprocesor is pretty limited, but this sounds like something Paul M. told me was undefined.
No, I'm not sure. I believe you if you tell me it's undefined. We might need another comma.
Now I don't believe you anymore. See the example at http://www.boost.org/libs/preprocessor/doc/ref/enum_params.html
Okay, good. Maybe it's only using # that's undefined. Jonathan

Are you sure it's legal to take "< 3" and paste on the remaining characters, e.g., "0404"? My knowledge of the preprocesor is pretty limited, but this sounds like something Paul M. told me was undefined.
Missed this. It isn't undefined. The operands of the token-pasting operator are only the two tokens immediately adjacent to it. However, if one of these operands is part of an argument, it has the effect of disabling argument expansion for the entire argument. I.e. it acts only on two tokens, but it affects expansion of the entire argument. Regards, Paul Mensonides

From: "Jonathan Turkanis" <technews@kangaroologic.com>
You could also do
BOOST_WORKAROUND(GCC, LESS(3,2,3)) BOOST_WORKAROUND(GCC, LESS_EQ(3,2,3)) BOOST_WORKAROUND(GCC, TESTED_AT(3,2,3)) ...
Those look nice, too. You could also simplify the "LESS," "LESS_EQ," etc. operators with the common abbreviations: LT, LE, GT, GE, and even EQ. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart wrote:
From: "Jonathan Turkanis" <technews@kangaroologic.com>
You could also do
BOOST_WORKAROUND(GCC, LESS(3,2,3)) BOOST_WORKAROUND(GCC, LESS_EQ(3,2,3)) BOOST_WORKAROUND(GCC, TESTED_AT(3,2,3)) ...
You could also simplify the "LESS," "LESS_EQ," etc. operators with the common abbreviations: LT, LE, GT, GE, and even EQ.
Common in which world? Perl, HTML entities, assembler? I think that somebody will decipher LE as LEss instead of Less or Equal. We aren't going to reduce or to increase the size. We just want to increase clarity for plain users. I like BOOST_WORKAROUND_TESTED_AT(GCC, 3,2,3) What about BOOST_WORKAROUND_BEFORE(GCC, 3,2,3) BOOST_WORKAROUND_AFTER(GCC, 3,2,3) BOOST_WORKAROUND_STARTING_FROM(GCC, 3,2,3) and other plain English words instead of syntactic tricks with putting < signs as macro parameters? Is it going to be more verbose and cryptic than using macrost with < ? Here are real life examples from intrusive_ptr.hpp and mem_fn.hpp: #elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__MWERKS__, < 0x3200) How we are going to transform the latter? #if !BOOST_WORKAROUND_BEFORE(MSVC, 8,0,0) && !BOOST_WORKAROUND_BEFORE(MWERKS, 9,0,1) Can we get rid of these "!" signs? !a && !b looks too verbose to me. But of course !BOOST_WORKAROUND(__MWERKS__, < 0x3200) isn't equivalent to BOOST_WORKAROUND(__MWERKS__, >= 0x3200) I wonder if such a change would improve readability: #if BOOST_WORKAROUND_BEFORE(MSVC, 8,0,0) || BOOST_WORKAROUND_BEFORE(MWERKS, 9,0,1) // () operator cannot be used on certain compilers #else R & operator()(T & t) const { return (t.*f_); } #endif Andrey

Andrey Melnikov <melnikov@simplexsoft.com> writes:
What about
BOOST_WORKAROUND_BEFORE(GCC, 3,2,3) BOOST_WORKAROUND_AFTER(GCC, 3,2,3) BOOST_WORKAROUND_STARTING_FROM(GCC, 3,2,3)
and other plain English words instead of syntactic tricks with putting < signs as macro parameters? Is it going to be more verbose and cryptic than using macrost with < ?
Why do you call that a "syntactic trick?" The operator gets used in the macro expansion and ends up being used by the preprocessor with the obvious semantics. Just about every other token in BOOST_WORKAROUND(GCC, >, 3,2,3) is trickier than the ">". The desire to spell out comparison operations as english words seems akin to the desire to embed compiler/ide versions in macro names.
Here are real life examples from intrusive_ptr.hpp and mem_fn.hpp:
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__MWERKS__, < 0x3200)
How we are going to transform the latter?
#if !BOOST_WORKAROUND_BEFORE(MSVC, 8,0,0) && !BOOST_WORKAROUND_BEFORE(MWERKS, 9,0,1)
Ick. #if !BOOST_WORKAROUND(MSVC, <=, 7,0,0) && !BOOST_WORKAROUND(MWERKS, <, 9,0,0)
Can we get rid of these "!" signs?
!a && !b
looks too verbose to me.
You can always write: #if !(BOOST_WORKAROUND(MSVC, <=, 7,0,0) || BOOST_WORKAROUND(MWERKS, <, 9,0,0)) but it's not much better.
But of course
!BOOST_WORKAROUND(__MWERKS__, < 0x3200)
isn't equivalent to
BOOST_WORKAROUND(__MWERKS__, >= 0x3200)
The ! signs come from people having a desire to put the non-workaround code first, but that IMO is a misguided effort, since it begins to get nasty once you have more than one workaround: #if !BOOST_WORKAROUND( xxx ) && !BOOST_WORKAROUND( yyy ) && !BOOST_WORKAROUND( zzz ) .. #elif BOOST_WORKAROUND( xxx ) ... #elif BOOST_WORKAROUND( yyy ) ... #elif BOOST_WORKAROUND( zzz ) ... #endif It's so much simpler as: #if BOOST_WORKAROUND( xxx ) ... #elif BOOST_WORKAROUND( yyy ) ... #elif BOOST_WORKAROUND( zzz ) ... #else ... #endif -- Dave Abrahams Boost Consulting www.boost-consulting.com

"Peter Dimov" <pdimov@mmltd.net> writes:
David Abrahams wrote:
The ! signs come from people having a desire to put the non-workaround code first, ...
No, it comes from cases where there is no workaround code. The code is just omitted on some compilers.
Whoops, I prob'ly should've looked at the code. Sorry :( -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Andrey Melnikov <melnikov@simplexsoft.com> writes:
What about
BOOST_WORKAROUND_BEFORE(GCC, 3,2,3) BOOST_WORKAROUND_AFTER(GCC, 3,2,3) BOOST_WORKAROUND_STARTING_FROM(GCC, 3,2,3)
and other plain English words instead of syntactic tricks with putting < signs as macro parameters? Is it going to be more verbose and cryptic than using macrost with < ?
Why do you call that a "syntactic trick?" The operator gets used in the macro expansion and ends up being used by the preprocessor with the obvious semantics. Just about every other token in
BOOST_WORKAROUND(GCC, >, 3,2,3)
is trickier than the ">".
I didn't mean a preprocessor trick. I only mean that for people it's unusual to see ">" sign alone or in an "unary" notation like "> 030203". They will have to look at the macro itself to see how this ">" works.
The desire to spell out comparison operations as english words seems akin to the desire to embed compiler/ide versions in macro names.
It really is akin. I'd like to see something more transparent and intuitive. I don't like the idea with words very much, but I don't like ">" s
#if !BOOST_WORKAROUND(MSVC, <=, 7,0,0) && !BOOST_WORKAROUND(MWERKS, <, 9,0,0)
Can we get rid of these "!" signs?
!a && !b
looks too verbose to me.
You can always write:
#if !(BOOST_WORKAROUND(MSVC, <=, 7,0,0) || BOOST_WORKAROUND(MWERKS, <, 9,0,0))
but it's not much better.
Do you think an empty branch and #else is worse than "!" ? Negations are rather hard to decipher. #if BOOST_WORKAROUND(MSVC, <=, 7,0,0) || BOOST_WORKAROUND(MWERKS, <, 9,0,0) // these compilers doesn't support these features #else // actual code for cases when no workarounds are nesessary #endif I always decode the former expression to the latter in my mind. I think #else is a better way to express a negation than "!" in this case. Andrey

Andrey Melnikov <melnikov@simplexsoft.com> writes:
David Abrahams wrote:
Andrey Melnikov <melnikov@simplexsoft.com> writes:
Just about every other token in
BOOST_WORKAROUND(GCC, >, 3,2,3)
is trickier than the ">".
I didn't mean a preprocessor trick. I only mean that for people it's unusual to see ">" sign alone or in an "unary" notation like "> 030203". They will have to look at the macro itself to see how this ">" works.
That goes double for all the other arguments to BOOST_WORKAROUND.
The desire to spell out comparison operations as english words seems akin to the desire to embed compiler/ide versions in macro names.
It really is akin. I'd like to see something more transparent and intuitive. I don't like the idea with words very much, but I don't like ">" s
I'm sorry; I can't imagine what could be more intuitive and transparent than using ">" to mean "is greater than."
#if !BOOST_WORKAROUND(MSVC, <=, 7,0,0) && !BOOST_WORKAROUND(MWERKS, <, 9,0,0)
Can we get rid of these "!" signs?
!a && !b
looks too verbose to me.
You can always write:
#if !(BOOST_WORKAROUND(MSVC, <=, 7,0,0) || BOOST_WORKAROUND(MWERKS, <, 9,0,0))
but it's not much better.
Do you think an empty branch and #else is worse than "!" ?
Yes, a little bit worse. It looks like someobody made a mistake and left out the #if clause.
Negations are rather hard to decipher.
Some "problems" don't need to be solved, IMO, and the supposed inability of some programmers to read C++ logical expressions is one of them.
#if BOOST_WORKAROUND(MSVC, <=, 7,0,0) || BOOST_WORKAROUND(MWERKS, <, 9,0,0) // these compilers doesn't support these features #else // actual code for cases when no workarounds are nesessary #endif
I always decode the former expression to the latter in my mind. I think #else is a better way to express a negation than "!" in this case.
Why? -- Dave Abrahams Boost Consulting www.boost-consulting.com

From: David Abrahams <dave@boost-consulting.com>
Or we could arrange to write:
#if BOOST_WORKAROUND(BOOST_GCC,< 3,2,3)
Nobody likes that one?
I like it. I just didn't think I needed to say so!
What about:
#if BOOST_WORKAROUND(GCC,< 3,2,3)
Pretty succinct, I think.
Since BOOST_WORKAROUND can put the "BOOST_" prefix on it to keep it safe (that is, to refer to BOOST_GCC and not to GCC), the succinctness is a real help.
I'm not sure about getting BOOST_TESTED_AT to work here.
#if BOOST_WORKAROUND(GCC, BOOST_TESTED_AT 3,2,3)
would be nice syntax, but I'm just not sure how workable it is. We may end up with
#if BOOST_WORKAROUND_TESTED_AT(GCC, 3,2,3)
which is actually pretty nice and requires fewer fancy tricks to implement.
I like the looks of what Jonathan proposed. But these look fine, too. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

From: Tobias Schwinger <tschwinger@neoscientists.org>
Jonathan Turkanis wrote:
The ability to accommodate these unlikely scenarios has to be balanced against usability. If a test for GCC with major version < 3 has to use "3000000," chances are good that a test will be misspelled and a needed workaround will not be applied.
It is possible to put an expression to calculate the 3000000 in this case into a macro:
#define BOOST_VERSION(major,minor,patchlvl) \ (major * 1000000 + minor * 1000 + patchlvl)
#define BOOST_GCC \ BOOST_GCC_VERSION(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
s/BOOST_GCC_VERSION/BOOST_VERSION/
Example:
#if BOOST_WORKAROUND(BOOST_GCC,< BOOST_VERSION(3,2,3)) // ... #endif
It's a nice idea which neatly circumvents the octal problem and the N digit problem. BOOST_VERSION could be updated at any time to handle a compiler that used more digits. For now, the multipliers could be 10000 and 100. To use BOOST_VERSION, however, all compilers would need a BOOST_XXX macro that encodes the native version number into a BOOST_VERSION-compatible number. For GCC, that would be BOOST_GCC as shown above. For MSVC, it would be more painful, but still tenable, I think. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart <stewart@sig.com> writes:
From: Jonathan Wakely <cow@compsoc.man.ac.uk>
On Tue, Jul 12, 2005 at 10:55:37AM -0400, Rob Stewart wrote:
What's to stop any compiler from using a 3 digit version number sometime in the future? Yes, GCC has moved on to 4.x, so there's no 3.x version even close to that, and there aren't likely to be (m)any more 2.x releases, but if you are going to choose a convention, it ought to account for forseeable problems, right?
Unless it makes things too hard to read. With typically seven digits in a number it gets hard to divide them into groups of 3. Note that all the numbers above are wrong because they're octal. You can't use a leading zero, so typically we'll be looking at 5 digits. what's-to-stop-them-from-using-a-4-digit-number-ly y'rs, dave -- Dave Abrahams Boost Consulting www.boost-consulting.com

From: David Abrahams <dave@boost-consulting.com>
Rob Stewart <stewart@sig.com> writes:
From: Jonathan Wakely <cow@compsoc.man.ac.uk>
On Tue, Jul 12, 2005 at 10:55:37AM -0400, Rob Stewart wrote:
What's to stop any compiler from using a 3 digit version number sometime in the future? Yes, GCC has moved on to 4.x, so there's no 3.x version even close to that, and there aren't likely to be (m)any more 2.x releases, but if you are going to choose a convention, it ought to account for forseeable problems, right?
Unless it makes things too hard to read. With typically seven digits in a number it gets hard to divide them into groups of 3.
It isn't *that* hard, but I do understand your point.
Note that all the numbers above are wrong because they're octal. You can't use a leading zero, so typically we'll be looking at 5 digits.
That goes to show how often I write octal! I'd forgotten that. We could prepend a 1 to all such numbers, just so they can have leading zeroes for all components. That makes them longer still, of course.
what's-to-stop-them-from-using-a-4-digit-number-ly y'rs,
That's always possible, but terribly unlikely, especially in light of arguments suggesting three digit numbers were unlikely. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart <stewart@sig.com> writes:
From: David Abrahams <dave@boost-consulting.com>
Edward Diener <eddielee@tropicsoft.com> writes:
Okay, I understand what you're driving at. I'm not sure if going down this road is worth the trouble, but if it is, I'd rather see a standard system for referring to versions numerically. So, for example:
Version Value ------- ----- 6.0 060000 6.0sp5 060005 7.0 070000 7.1 070100 5.3.4 050304 3.4.3 030403 2.95.3 029503
You probably need to allow another digit for each field. 95 is awfully close to rolling over to three digits.
Well, the only compiler that's ever approached that number is GCC, and they are recommending 2-digit fields. I don't think numbers over 20 will come up -- to say nothing of numbers over 99! -- in the forseeable future. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
one could create a series of macros, let us say for VC71, like this:
// These are always defined and included in a header file at the top of select_compiler_config.hpp
#define BOOST_COMPILER_VC _MSC_VER
It's a lot more complicated than that, unfortunately, because many other compilers define _MSC_VER to "act compatible" with VC++.
Yes, I understand that. In that case it should be: #define BOOST_COMPILER_VC 0 in the in the header file to be included at the top of select_compiler_config.h and #define BOOST_COMPILER_VC _MSC_VER only in the header file included at the top of visualc.hpp whern that is the compiler selected. The idea, for any compiler, is that the preprocessor symbol name need not be remembered for BOOST_WORKAROUND's first parameter but that instead one would use a much easier name like BOOST_COMPILER_VC for Visual C++ or BOOST_COMPILER_BORLAND for C++ Builder etc. In fact an actual case supporting this idea was recently posted on this NG, where someone erroneously used BORLANDC instead of __BORLANDC__ in such a manner. My suggesting is to eliminate this sort of error by providing an easier to remember macro name instead.
You could now say:
#if BOOST_WORKAROUND(BOOST_COMPILER_VC,BOOST_COMPILER_VC71_VERSION) // code #endif
or, in a different situation:
#if BOOST_WORKAROUND(BOOST_COMPILER_VC,BOOST_TESTED_AT(BOOST_COMPILER_VC71_VERSION_HIGH)) // code #endif
or, in a different situation:
#if BOOST_COMPILER_VC71 // and any other combinations you like // code #endif
Okay, I understand what you're driving at. I'm not sure if going down this road is worth the trouble, but if it is, I'd rather see a standard system for referring to versions numerically. So, for example:
Version Value ------- ----- 6.0 060000 6.0sp5 060005 7.0 070000 7.1 070100 5.3.4 050304 3.4.3 030403 2.95.3 029503
I don't particularly think
BOOST_COMPILER_VC == BOOST_COMPILER_VC71_VERSION
is more expressive than
BOOST_MSVC_VERSION == 070100
It is more expressive than some long number because the former encompasses the idea of a version of Microsoft VC++. I am trying to create a set of macros which equate to version numbers of compiler releases but which also allow boolean comparisons for that release. That is why I have BOOST_COMPILER_XXX_VERSION and BOOST_COMPILER_XXX_VERSION_HIGH for the former and BOOST_COMPILER_XXX, BOOST_COMPILER_XXX_OR_HIGHER, and BOOST_COMPILER_XXX_OR_LOWER for the latter.
Nor do I think
BOOST_COMPILER_VC <= BOOST_COMPILER_VC71_VERSION_HIGH
is an improvement over
BOOST_MSVC_VERSION < 070200
I am sorry I can not make you see that and you still want programmers to refer to version numbers as numbers.
If you are arguing for only using BOOST_WORKAROUND, and never using a construct like the last one
Among other things, I am.
Let us suppose that one has workaround code only for BCB6. Currently, because BCB6 encompasses definitions of __BORLANDC__ between 0x560 and 0x564, using BOOST_WORKAROUND one would have to write to be completely correct: #if BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, <= 0x564) // code #endif whereas with my macros one would write: #if BOOST_WORKAROUND(BOOST_COMPILER_BORLAND,BOOST_COMPILER_BCB6_VERSION) && BOOST_WORKAROUND(BOOST_COMPILER_BORLAND,BOOST_COMPILER_BCB6_VERSION_HIGH) // code #endif or even the much more succinct #if BOOST_COMPILER_BCB6 // code #endif Granted that BOOST_WORKAROUND is more flexible than what I have presented, given the practical case above, which I think is very prevalent in Boost code, which do you really see as more understandable and easier to write ? My point is that while BOOST_WORKAROUND is a very good solution in many cases, it is not the only solution which should be considered.
then you are advocating always using specific version numbers.
I don't know what you mean.
I meant that you want the programmer to have to know actual numbers relating to preprocessor macros, such as _MSC_VER and __BORLANDC__, for a particular version of a particular product. I want to bury the need to have this knowledge as much as possible while realizing it may still be needed for some situations. I believe, from looking at the workaround code I have seen in Boost, that the number of times such knowledge is actually needfed for workarounds is minimal compared to the knowledge that a particular workaround is needed for a particular specific version or specific versions of a compiler.
In that case you may want to consider at least forms like BOOST_COMPILER_VC71_VERSION and BOOST_COMPILER_VC71_VERSION_HIGH useful for your BOOST_WORKAROUND and BOOST_TESTED_AT macros.
I understand why you want it, but am not fond of your proposed names and syntax.
I could care less about the proposed names, as long as the idea were acceptable. However if you do not find the idea acceptable, I will not burden you further with arguments for it. Hopefully it will at least have thrown out a few useful ideas for the future which make specifying workarounds for non-compliant compiler/versions easier to do. Of course it is my fervent hope that fewer workarounds will be needed as compilers pursue C++ standard compliancy.

From: Edward Diener <eddielee@tropicsoft.com>
David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
BOOST_COMPILER_VC == BOOST_COMPILER_VC71_VERSION
is more expressive than
BOOST_MSVC_VERSION == 070100
It is more expressive than some long number because the former encompasses the idea of a version of Microsoft VC++. I am trying to create a set of macros which
Not at all. That the comparison is against BOOST_MSVC_VERSION makes quite clear the purpose of the expression. Then, were it a proper value, "070100" would clearly indicate a check for v7.1SP0. What's not expressive about that? IOW, "070100" is far clearer than "BOOST_COMPILER_VC71_VERSION."
equate to version numbers of compiler releases but which also allow boolean comparisons for that release. That is why I have BOOST_COMPILER_XXX_VERSION and BOOST_COMPILER_XXX_VERSION_HIGH for the former and BOOST_COMPILER_XXX, BOOST_COMPILER_XXX_OR_HIGHER, and BOOST_COMPILER_XXX_OR_LOWER for the latter.
With numbers, you get all of that for free and there aren't any ugly names!
Nor do I think
BOOST_COMPILER_VC <= BOOST_COMPILER_VC71_VERSION_HIGH
is an improvement over
BOOST_MSVC_VERSION < 070200
I am sorry I can not make you see that and you still want programmers to refer to version numbers as numbers.
I'm sorry we haven't gotten you to see the value of standardized numbers.
Let us suppose that one has workaround code only for BCB6. Currently, because BCB6 encompasses definitions of __BORLANDC__ between 0x560 and 0x564, using BOOST_WORKAROUND one would have to write to be completely correct:
#if BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, <= 0x564) // code #endif
No! The point is that one would use a standardized macro like BOOST_BCB_VERSION, not __BORLANDC__. Furthermore, the comparison would be >= 050600 and < 050700 (or, with the idea from another branch of this thread, >= BOOST_VERSION(5,6,0) and < BOOST_VERSION(5,7,0)). That's flexible, standardized, and clear!
whereas with my macros one would write:
#if BOOST_WORKAROUND(BOOST_COMPILER_BORLAND,BOOST_COMPILER_BCB6_VERSION) && BOOST_WORKAROUND(BOOST_COMPILER_BORLAND,BOOST_COMPILER_BCB6_VERSION_HIGH)
That's incomprehensible.
or even the much more succinct
#if BOOST_COMPILER_BCB6 // code #endif
Granted that BOOST_WORKAROUND is more flexible than what I have presented, given the practical case above, which I think is very prevalent in Boost code, which do you really see as more understandable and easier to write ? My point is that
Your last solution only works if one wants to create and maintain an ever increasing set of named/versioned macros. Given that the conditional compilation being controlled isn't, in general so neat as to apply to all patch levels of a single major version of a compiler, your solution breaks down. The alternative is comprehensible and provides the ability to express every necessary combination. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Edward Diener <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
The idea, for any compiler, is that the preprocessor symbol name need not be remembered for BOOST_WORKAROUND's first parameter but that instead one would use a much easier name like BOOST_COMPILER_VC for Visual C++ or BOOST_COMPILER_BORLAND for C++ Builder etc. In fact an actual case supporting this idea was recently posted on this NG, where someone erroneously used BORLANDC instead of __BORLANDC__ in such a manner. My suggesting is to eliminate this sort of error by providing an easier to remember macro name instead.
I already said I supported such an idea long ago in this thread (maybe my 1st or 2nd post?). For Visual C++ the current macro is BOOST_MSVC I don't see a strong need to add "COMPILER_". However, people will still be able to misspell these macros unfortunately.
Okay, I understand what you're driving at. I'm not sure if going down this road is worth the trouble, but if it is, I'd rather see a standard system for referring to versions numerically. So, for example:
Version Value ------- ----- 6.0 060000 6.0sp5 060005 7.0 070000 7.1 070100 5.3.4 050304 3.4.3 030403 2.95.3 029503
I don't particularly think
BOOST_COMPILER_VC == BOOST_COMPILER_VC71_VERSION
is more expressive than
BOOST_MSVC_VERSION == 070100
It is more expressive than some long number because the former encompasses the idea of a version of Microsoft VC++. I am trying to create a set of macros which equate to version numbers of compiler releases but which also allow boolean comparisons for that release. That is why I have BOOST_COMPILER_XXX_VERSION and BOOST_COMPILER_XXX_VERSION_HIGH for the former and BOOST_COMPILER_XXX, BOOST_COMPILER_XXX_OR_HIGHER, and BOOST_COMPILER_XXX_OR_LOWER for the latter.
To me it looks like a maintenance nightmare, hard to learn, and overly verbose to use.
Nor do I think
BOOST_COMPILER_VC <= BOOST_COMPILER_VC71_VERSION_HIGH
is an improvement over
BOOST_MSVC_VERSION < 070200
I am sorry I can not make you see that and you still want programmers to refer to version numbers as numbers.
Life is tough that way, isn't it? I am sorry that you still want programmers to use long symbolic macros to label things that are in fact numbers.
If you are arguing for only using BOOST_WORKAROUND, and never using a construct like the last one
Among other things, I am.
Let us suppose that one has workaround code only for BCB6. Currently, because BCB6 encompasses definitions of __BORLANDC__ between 0x560 and 0x564, using BOOST_WORKAROUND one would have to write to be completely correct:
#if BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, <= 0x564) // code #endif
whereas with my macros one would write:
#if BOOST_WORKAROUND(BOOST_COMPILER_BORLAND,BOOST_COMPILER_BCB6_VERSION) && BOOST_WORKAROUND(BOOST_COMPILER_BORLAND,BOOST_COMPILER_BCB6_VERSION_HIGH) // code #endif
Sorry, but that's horrible, IMO. Aside from it being terribly verbose and too uniform visually to be easy to read, I'm left wondering what BCB6 has to do with anything. I care about the version of my compilers, not the version of the product that's built around them. Presumably I could plug any compiler into BCB6. Also, #if BOOST_WORKAROUND(__BORLANDC__, & 0xFF8 == 0x560) // <wink> But more imporanatly, this scenario of a workaround that is needed for a range of versions that's closed on both ends doesn't come up often enough in practice to be very important.
or even the much more succinct
#if BOOST_COMPILER_BCB6 // code #endif
C'mon, we've been over this. The _functionality_ of BOOST_WORKAROUND is important.
Granted that BOOST_WORKAROUND is more flexible than what I have presented, given the practical case above, which I think is very prevalent in Boost code, which do you really see as more understandable and easier to write ? My point is that while BOOST_WORKAROUND is a very good solution in many cases, it is not the only solution which should be considered.
Whatever we do, if we're going to change anything we should go through the code and change everything. Adding another way to do the same things in Boost would be much worse than doing nothing at all.
then you are advocating always using specific version numbers.
I don't know what you mean.
I meant that you want the programmer to have to know actual numbers relating to preprocessor macros, such as _MSC_VER and __BORLANDC__,
No I don't, and that should be clear from my other posts by now. I do think the actual version number of the compiler is important.
In that case you may want to consider at least forms like BOOST_COMPILER_VC71_VERSION and BOOST_COMPILER_VC71_VERSION_HIGH useful for your BOOST_WORKAROUND and BOOST_TESTED_AT macros.
I understand why you want it, but am not fond of your proposed names and syntax.
I could care less about the proposed names, as long as the idea were acceptable. However if you do not find the idea acceptable, I will not burden you further with arguments for it.
Well, I'm not the only one around; you could convince someone else. However, I hope I've made my personal position clear enough by now that I can stop arguing about this. What about my other suggestion, #if BOOST_WORKAROUND(BOOST_GCC,< 3,2,3) -- Dave Abrahams Boost Consulting www.boost-consulting.com

Edward Diener <eddielee@tropicsoft.com> writes:
I also think Boost should have somewhere a document or table which relates each distinct version of a compiler to a range of the appropriate preprocessor version numbers. If one has the compiler on one's machine, I believe the config.cpp test will tell that, but if one does not have the compiler it is impossible to tell.
I think that would be a good step. Why don't you write up such a page? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
I also think Boost should have somewhere a document or table which relates each distinct version of a compiler to a range of the appropriate preprocessor version numbers. If one has the compiler on one's machine, I believe the config.cpp test will tell that, but if one does not have the compiler it is impossible to tell.
I think that would be a good step. Why don't you write up such a page?
I do not mind doing that for the compilers I have on my machine, but I would need others to supply me with macro names and numbers for the many compilers which i do not have. I will ask others to help me compile such information. Once I have such a web page, how do I get it displayed somewhere in Boost ?

Edward Diener <eddielee@tropicsoft.com> writes:
David Abrahams wrote:
Edward Diener <eddielee@tropicsoft.com> writes:
I also think Boost should have somewhere a document or table which relates each distinct version of a compiler to a range of the appropriate preprocessor version numbers. If one has the compiler on one's machine, I believe the config.cpp test will tell that, but if one does not have the compiler it is impossible to tell.
I think that would be a good step. Why don't you write up such a page?
I do not mind doing that for the compilers I have on my machine, but I would need others to supply me with macro names and numbers for the many compilers which i do not have. I will ask others to help me compile such information.
Great.
Once I have such a web page, how do I get it displayed somewhere in Boost ?
Post a patch for the website against the current CVS, including links to your page, to the SF bug tracker. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (11)
-
Allen
-
Andrey Melnikov
-
David Abrahams
-
Edward Diener
-
Jonathan Turkanis
-
Jonathan Wakely
-
Paul Mensonides
-
Peter Dimov
-
Rob Stewart
-
Tobias Schwinger
-
Ulrich Eckhardt