Single letter template type causes errors in compile of program_options and filesystem boost libraries

Hi, Problem lIbraries: program_options and filesystems Version: Release 1.37.0 System: Mac OS X 10.5.6, Red Hat Linux Enterprise 4, Red Hat Linux Enterprise 3 Compiler : gcc 4.0 and gcc 3.3 I have just started trying to use the boost libraries. I tried starting with program options and filesystem. Unfortunately both of these do not compile in my environment because of the use of single letter variable and template types. For example in alignment_of.hpp the template: template <unsigned A, unsigned S> struct alignment_logic { BOOST_STATIC_CONSTANT(std::size_t, value = A < S ? A : S); }; causes error and in operators.hpp the template: // Import a 3-type-argument operator template into boost (if necessary) and // provide a specialization of 'is_chained_base<>' for it. # define BOOST_OPERATOR_TEMPLATE3(template_name3) \ BOOST_IMPORT_TEMPLATE3(template_name3) \ template<class T, class U, class V, class B> \ struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \ typedef ::boost::detail::true_t value; \ }; causes errors. The errors are the result of using single letters for variables or template types. The reason for the errors is in my compile environment ( electrical engineering related ) defines are used for the convenience of writing units in code. These defines exist in a vendor supplied header in my project: #define A #define V #define W #define s #define S #define J among many others to denote units ( in these defines the units are Amps, Volts, Watts, Seconds, and Joules ). These defines come from the vendor of the software I am using and can't be easily changed. I believe the correct change is to use longer names for variables and template types in the boost library headers, which means changing the boost library headers. I can do this locally in my copy of the headers, but it seems to me a better design is to use longer names in the boost libraries in first place. I don't see any benefit to using the single letter names in the boost library headers. Does anyone have other solutions to this problem or know of reasons why single letter variable and template type names are used in the boost libraries? Thanks, Mike

Mike Collier wrote:
The errors are the result of using single letters for variables or template types. The reason for the errors is in my compile environment ( electrical engineering related ) defines are used for the convenience of writing units in code. These defines exist in a vendor supplied header in my project:
#define A #define V #define W #define s #define S #define J
Sorry, but this is just bad coding practice. Instead of changing boost in order to accomodate for it, I suggest that you isolate the libraries from each other, by carefully undefining those single-letter macros prior to including boost. If something should use longer names, it's these macros in your library, not boost template parameters. Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Stefan Seefeld wrote:
Mike Collier wrote:
The errors are the result of using single letters for variables or template types. The reason for the errors is in my compile environment ( electrical engineering related ) defines are used for the convenience of writing units in code. These defines exist in a vendor supplied header in my project:
#define A #define V #define W #define s #define S #define J
Sorry, but this is just bad coding practice. Instead of changing boost in order to accomodate for it, I suggest that you isolate the libraries from each other, by carefully undefining those single-letter macros prior to including boost.
Another solution might be simply changing include order, so that boost headers get included prior to the vendor-provided headers.
If something should use longer names, it's these macros in your library, not boost template parameters.
Since this library is not Mike's, I'd rather suggest reporting this issue to the library vendor.

On Thu, Dec 18, 2008 at 3:51 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Stefan Seefeld wrote: ...
Sorry, but this is just bad coding practice. Instead of changing boost in order to accomodate for it, I suggest that you isolate the libraries from each other, by carefully undefining those single-letter macros prior to including boost.
Another solution might be simply changing include order, so that boost headers get included prior to the vendor-provided headers.
It might be better not include the vendor-provided headers at all, since it would not be surprising if these headers had many other additional problems. Better to provide a modern, safe interface via your own headers, implemented in an isolated translation unit that calls the vendor's functionality.
If something should use longer names, it's these macros in your library, not boost template parameters.
Since this library is not Mike's, I'd rather suggest reporting this issue to the library vendor.
Yep. One wonders what they could have been thinking and why they used macros rather than something that observed scoping. --Beman

Thanks for the suggestions. On Dec 18, 2008, at 1:37 PM, Beman Dawes wrote:
On Thu, Dec 18, 2008 at 3:51 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Stefan Seefeld wrote: ...
Sorry, but this is just bad coding practice. Instead of changing boost in order to accomodate for it, I suggest that you isolate the libraries from each other, by carefully undefining those single-letter macros prior to including boost.
Another solution might be simply changing include order, so that boost headers get included prior to the vendor-provided headers.
It might be better not include the vendor-provided headers at all, since it would not be surprising if these headers had many other additional problems. Better to provide a modern, safe interface via your own headers, implemented in an isolated translation unit that calls the vendor's functionality.
It's not really to practical to leave out the vendor header because the defines are used a lot in code. Not using them would give incorrect results or cause the compile to fail in code written such as this voltage = 10 V; current = 100 uA; where uA is : #define uA *1.000000e-06 These are connivence ( or I might say crutch ) defines for electrical engineers who don't want to code with proper exponents or want a little documentation in the code. I know this is a bad practice but it's in a header that's vendor supplied and these connivence defines are used in lot's of code.
If something should use longer names, it's these macros in your library, not boost template parameters.
Since this library is not Mike's, I'd rather suggest reporting this issue to the library vendor.
Yep. One wonders what they could have been thinking and why they used macros rather than something that observed scoping.
The vendor ( Verigy ) is not known by people who use their software as having good software so it's not surprising to me they coded their macros this way. They probably thought it would be nice if non- programmer electrical engineers could use units next to numbers to save time or make code self documenting. I doubt they would be willing to change the header since it's used around the world in legacy code that would all fail the compile or worse compile and give incorrect results. My solution is to change type names in the boost headers , since I can control these locally and I don't see any benefit to using short names in the boost headers. My ideal solution would be for the boost headers to use longer names to start with. Any other ideas are welcome. Thanks, Mike

On Thu, Dec 18, 2008 at 3:09 PM, Mike Collier <mcollier69@gmail.com> wrote:
Thanks for the suggestions.
On Dec 18, 2008, at 1:37 PM, Beman Dawes wrote:
On Thu, Dec 18, 2008 at 3:51 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Stefan Seefeld wrote:
...
Sorry, but this is just bad coding practice. Instead of changing boost in order to accomodate for it, I suggest that you isolate the libraries from each other, by carefully undefining those single-letter macros prior to including boost.
Another solution might be simply changing include order, so that boost headers get included prior to the vendor-provided headers.
It might be better not include the vendor-provided headers at all, since it would not be surprising if these headers had many other additional problems. Better to provide a modern, safe interface via your own headers, implemented in an isolated translation unit that calls the vendor's functionality.
It's not really to practical to leave out the vendor header because the defines are used a lot in code. Not using them would give incorrect results or cause the compile to fail in code written such as this
voltage = 10 V; current = 100 uA;
where uA is : #define uA *1.000000e-06
These are connivence ( or I might say crutch ) defines for electrical engineers who don't want to code with proper exponents or want a little documentation in the code. I know this is a bad practice but it's in a header that's vendor supplied and these connivence defines are used in lot's of code.
If something should use longer names, it's these macros in your library, not boost template parameters.
Since this library is not Mike's, I'd rather suggest reporting this issue to the library vendor.
Yep. One wonders what they could have been thinking and why they used macros rather than something that observed scoping.
The vendor ( Verigy ) is not known by people who use their software as having good software so it's not surprising to me they coded their macros this way. They probably thought it would be nice if non-programmer electrical engineers could use units next to numbers to save time or make code self documenting. I doubt they would be willing to change the header since it's used around the world in legacy code that would all fail the compile or worse compile and give incorrect results.
My solution is to change type names in the boost headers , since I can control these locally and I don't see any benefit to using short names in the boost headers. My ideal solution would be for the boost headers to use longer names to start with.
Any other ideas are welcome.
The thing is, the names in the boost headers are used as typenames, meaning that even if those were used as type or variable names anywhere else, it would not interfere at all. Those headers you use are using macros, which, to be blunt, is a rather stupid thing to do. If you wanted to enforce types between the electrical types, then Boost.MPL could make something like that quite easily (it is one of the example usages even), would be both self-documenting and type-safe (unlike their current broken macro defines that do nothing but cause problems). I do not think the Boost ones should be changes because, as stated, they are used as internal types that would mess with nothing else at all if other programmers were half intelligent. But why not, as was stated before, just include the boost header *before* you include the broken header?

On Thu, Dec 18, 2008 at 3:32 PM, OvermindDL1 <overminddl1@gmail.com> wrote:
On Thu, Dec 18, 2008 at 3:09 PM, Mike Collier <mcollier69@gmail.com> wrote:
Thanks for the suggestions.
On Dec 18, 2008, at 1:37 PM, Beman Dawes wrote:
On Thu, Dec 18, 2008 at 3:51 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Stefan Seefeld wrote:
...
Sorry, but this is just bad coding practice. Instead of changing boost in order to accomodate for it, I suggest that you isolate the libraries from each other, by carefully undefining those single-letter macros prior to including boost.
Another solution might be simply changing include order, so that boost headers get included prior to the vendor-provided headers.
It might be better not include the vendor-provided headers at all, since it would not be surprising if these headers had many other additional problems. Better to provide a modern, safe interface via your own headers, implemented in an isolated translation unit that calls the vendor's functionality.
It's not really to practical to leave out the vendor header because the defines are used a lot in code. Not using them would give incorrect results or cause the compile to fail in code written such as this
voltage = 10 V; current = 100 uA;
where uA is : #define uA *1.000000e-06
These are connivence ( or I might say crutch ) defines for electrical engineers who don't want to code with proper exponents or want a little documentation in the code. I know this is a bad practice but it's in a header that's vendor supplied and these connivence defines are used in lot's of code.
If something should use longer names, it's these macros in your library, not boost template parameters.
Since this library is not Mike's, I'd rather suggest reporting this issue to the library vendor.
Yep. One wonders what they could have been thinking and why they used macros rather than something that observed scoping.
The vendor ( Verigy ) is not known by people who use their software as having good software so it's not surprising to me they coded their macros this way. They probably thought it would be nice if non-programmer electrical engineers could use units next to numbers to save time or make code self documenting. I doubt they would be willing to change the header since it's used around the world in legacy code that would all fail the compile or worse compile and give incorrect results.
My solution is to change type names in the boost headers , since I can control these locally and I don't see any benefit to using short names in the boost headers. My ideal solution would be for the boost headers to use longer names to start with.
Any other ideas are welcome.
The thing is, the names in the boost headers are used as typenames, meaning that even if those were used as type or variable names anywhere else, it would not interfere at all. Those headers you use are using macros, which, to be blunt, is a rather stupid thing to do. If you wanted to enforce types between the electrical types, then Boost.MPL could make something like that quite easily (it is one of the example usages even), would be both self-documenting and type-safe (unlike their current broken macro defines that do nothing but cause problems). I do not think the Boost ones should be changes because, as stated, they are used as internal types that would mess with nothing else at all if other programmers were half intelligent.
But why not, as was stated before, just include the boost header *before* you include the broken header?
Or, make a wrapper header and just have undefine those if set, include the boost headers, then redefine them if they were defined before? Also quite easy. And here is the Boost.MPL page of exactly that kind of example; it would give them their self-documentation, as well as being typesafe, as well as helping to make sure the programmer cannot screw up and start multiplying things together that they should not do and so forth (would throw a compile error, you know, instead of their internal logic silently breaking down): http://www.boost.org/doc/libs/1_37_0/libs/mpl/doc/tutorial/dimensional-analy...

OvermindDL1 wrote:
And here is the Boost.MPL page of exactly that kind of example; it would give them their self-documentation, as well as being typesafe, as well as helping to make sure the programmer cannot screw up and start multiplying things together that they should not do and so forth (would throw a compile error, you know, instead of their internal logic silently breaking down): http://www.boost.org/doc/libs/1_37_0/libs/mpl/doc/tutorial/dimensional-analy...
If he wants to include units, he could avoid writing his own using MPL, and instead use the already existing boost units library. John

On Thu, Dec 18, 2008 at 4:02 PM, John Phillips <phillips@mps.ohio-state.edu> wrote:
OvermindDL1 wrote:
And here is the Boost.MPL page of exactly that kind of example; it would give them their self-documentation, as well as being typesafe, as well as helping to make sure the programmer cannot screw up and start multiplying things together that they should not do and so forth (would throw a compile error, you know, instead of their internal logic silently breaking down):
http://www.boost.org/doc/libs/1_37_0/libs/mpl/doc/tutorial/dimensional-analy...
If he wants to include units, he could avoid writing his own using MPL, and instead use the already existing boost units library.
...I never noticed that there before. When I update it is usually only because of a library or two, and I had been using an MPL homegrown version in one of my apps since boost 1.34. I may have to convert some of my code to Boost.Units if it support multi-dimensional positions, could remove a few rather large headers that way... I was not saying he should use it (I doubt that the library headers would change it anyway), I was just using it as an example of a proper way to signify types, rather then using empty macros that can conflict with a huge amount of code, thus showing that what Boost is doing is correct, and what that header is doing is horribly wrong.

Thanks for the insights and ideas. I looked at units and mpl. They look like something I could use if I was writing my own code dealing with units. I'll have to think about the wrapper script idea and using #undef and see if it may work in my case. Thanks, Mike On Dec 18, 2008, at 3:15 PM, OvermindDL1 wrote:
On Thu, Dec 18, 2008 at 4:02 PM, John Phillips <phillips@mps.ohio-state.edu> wrote:
OvermindDL1 wrote:
And here is the Boost.MPL page of exactly that kind of example; it would give them their self-documentation, as well as being typesafe, as well as helping to make sure the programmer cannot screw up and start multiplying things together that they should not do and so forth (would throw a compile error, you know, instead of their internal logic silently breaking down):
http://www.boost.org/doc/libs/1_37_0/libs/mpl/doc/tutorial/dimensional-analy...
If he wants to include units, he could avoid writing his own using MPL, and instead use the already existing boost units library.
...I never noticed that there before. When I update it is usually only because of a library or two, and I had been using an MPL homegrown version in one of my apps since boost 1.34. I may have to convert some of my code to Boost.Units if it support multi-dimensional positions, could remove a few rather large headers that way...
I was not saying he should use it (I doubt that the library headers would change it anyway), I was just using it as an example of a proper way to signify types, rather then using empty macros that can conflict with a huge amount of code, thus showing that what Boost is doing is correct, and what that header is doing is horribly wrong. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (6)
-
Andrey Semashev
-
Beman Dawes
-
John Phillips
-
Mike Collier
-
OvermindDL1
-
Stefan Seefeld