erroneous use of BOOST_STATIC_CONSTANT ?

When using BOOST_STATIC_CONSTANT, the member still need to be _defined_ in a .cpp file (IIUC 9.4.2 par 4 of the standard), unless the enum-trick is used, right? However gcc, intel-linux and the mipspro compiler (and probably others) do not require a seperate definition. OTOH IBM/VisualAge does really _need_ the definition (otherwise the symbols are undefined when linking). Would'nt it be better to advise library-developers to use an enum instead of BOOST_STATIC_CONSTANT if their library does not contain a definition? toon

Toon Knapen <toon.knapen@fft.be> writes:
When using BOOST_STATIC_CONSTANT, the member still need to be _defined_ in a .cpp file (IIUC 9.4.2 par 4 of the standard), unless the enum-trick is used, right?
Unless you believe the DR which says you don't need to do that.
However gcc, intel-linux and the mipspro compiler (and probably others) do not require a seperate definition. OTOH IBM/VisualAge does really _need_ the definition (otherwise the symbols are undefined when linking).
Would'nt it be better to advise library-developers to use an enum instead of BOOST_STATIC_CONSTANT if their library does not contain a definition?
Haven't we been over this many times before? I don't remember the rationale, but I guess the answer is no. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
Toon Knapen <toon.knapen@fft.be> writes:
When using BOOST_STATIC_CONSTANT, the member still need to be _defined_ in a .cpp file (IIUC 9.4.2 par 4 of the standard), unless the enum-trick is used, right?
Unless you believe the DR which says you don't need to do that.
But the question is. Do we comply with the standard of the DR ?
However gcc, intel-linux and the mipspro compiler (and probably others) do not require a seperate definition. OTOH IBM/VisualAge does really _need_ the definition (otherwise the symbols are undefined when linking).
Would'nt it be better to advise library-developers to use an enum instead of BOOST_STATIC_CONSTANT if their library does not contain a definition?
Haven't we been over this many times before? I don't remember the rationale, but I guess the answer is no.
AFAICT in the archives is says that a definition should be present: http://lists.boost.org/MailArchives/boost/msg59270.php http://lists.boost.org/MailArchives/boost/msg59273.php It is a pitty that there is no mention of this in http://www.boost.org/more/int_const_guidelines.htm (I have asked John Maddock about this (who has the copyright on this page) but I think he is on vacation or soth so I decided to contact the ml) toon

Toon Knapen wrote:
Would'nt it be better to advise library-developers to use an enum instead of BOOST_STATIC_CONSTANT if their library does not contain a definition?
The problem with that is that, an enum cannot store a 64-bit integer constant, which is needed in some cases. Matthias

On Fri, 09 Jul 2004 08:53:50 -0400, David Abrahams <dave@boost-consulting.com> wrote:
Toon Knapen <toon.knapen@fft.be> writes:
When using BOOST_STATIC_CONSTANT, the member still need to be _defined_ in a .cpp file (IIUC 9.4.2 par 4 of the standard), unless the enum-trick is used, right?
Unless you believe the DR which says you don't need to do that.
Do you mean my DR (#454)? BTW, one thing I wanted to ask (slightly off-topic): who is supposed to provide the new wording that the note at the end of the DR hints at? Me or someone in the committee? Thanks. -- Genny.

When using BOOST_STATIC_CONSTANT, the member still need to be _defined_ in a .cpp file (IIUC 9.4.2 par 4 of the standard), unless the enum-trick is used, right?
However gcc, intel-linux and the mipspro compiler (and probably others) do not require a seperate definition. OTOH IBM/VisualAge does really _need_ the definition (otherwise the symbols are undefined when linking).
Would'nt it be better to advise library-developers to use an enum instead of BOOST_STATIC_CONSTANT if their library does not contain a definition?
We've been through this before I think: We have one compiler (IBM's) that requires an out of line definition even when it's not required (and yes I realise it's a DR not the standard... yet), and another (Borland) which often gives the wrong result when an enum is used for compile time computations, and so *requires* the use of inline static constants and not enum's. To complicate things further, compilers are required to allow any integral constant expression to be stored in an enum, but several (including IBM's) won't store anything wider than an int: this also makes enum's unsuitable for use as integral constants in many cases. So... I guess we're just going to have to use real integral constants with IBM and supply out of line definitions as needed? John.

"John Maddock" <john@johnmaddock.co.uk> writes:
When using BOOST_STATIC_CONSTANT, the member still need to be _defined_ in a .cpp file (IIUC 9.4.2 par 4 of the standard), unless the enum-trick is used, right?
However gcc, intel-linux and the mipspro compiler (and probably others) do not require a seperate definition. OTOH IBM/VisualAge does really _need_ the definition (otherwise the symbols are undefined when linking).
Would'nt it be better to advise library-developers to use an enum instead of BOOST_STATIC_CONSTANT if their library does not contain a definition?
We've been through this before I think:
We have one compiler (IBM's) that requires an out of line definition even when it's not required (and yes I realise it's a DR not the standard... yet), and another (Borland) which often gives the wrong result when an enum is used for compile time computations, and so *requires* the use of inline static constants and not enum's. To complicate things further, compilers are required to allow any integral constant expression to be stored in an enum, but several (including IBM's) won't store anything wider than an int: this also makes enum's unsuitable for use as integral constants in many cases.
So... I guess we're just going to have to use real integral constants with IBM and supply out of line definitions as needed?
I wonder if it's possible to use preprocessor tricks to have BOOST_STATIC_CONSTANT generate enums (on IBM only) whenever they will fit? After all, integral constants _can_ be managed by the preprocessor. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

I wonder if it's possible to use preprocessor tricks to have BOOST_STATIC_CONSTANT generate enums (on IBM only) whenever they will fit? After all, integral constants _can_ be managed by the preprocessor.
So they can, but not with BOOST_STATIC_CONSTANT as is: BOOST_STATIC_CONSTANT(long long, value = 0ULL); as far as I know there's no way to do different things depending upon the second argument here, but I'd love to be proved wrong (and be very impressed as well!). John.

John Maddock wrote:
I wonder if it's possible to use preprocessor tricks to have BOOST_STATIC_CONSTANT generate enums (on IBM only) whenever they will fit? After all, integral constants _can_ be managed by the preprocessor.
So they can, but not with BOOST_STATIC_CONSTANT as is:
BOOST_STATIC_CONSTANT(long long, value = 0ULL);
as far as I know there's no way to do different things depending upon the second argument here, but I'd love to be proved wrong (and be very impressed as well!).
We already have BOOST_WORKAROUND. What I can do is provide a BOOST_WORKAROUND that will use an enum if the datatype is not too wide. Simple but effective! historical note: The reason I brought this up was because Mathias Troyer asked me to remove the BOOST_NO_INCLASS_MEMBER_INITIALIZATION in the config for vacpp version 6. And indeed, vacpp can handle the initialization but does not comply with the DR (so one can argue if BOOST_NO_INCLASS_MEMBER_INITALIZATION should be defined or not). Defining it however caused a problem in the random library however (Mathias can you recall what exactly happened and why). Next, should'nt it be a good idea to mention the policy on the out of line definition on http://www.boost.org/more/int_const_guidelines.htm (I'm willing to do it but a language lawyer among us should probably best revise it before I commit it).

On Jul 12, 2004, at 1:37 PM, Toon Knapen wrote:
John Maddock wrote:
I wonder if it's possible to use preprocessor tricks to have BOOST_STATIC_CONSTANT generate enums (on IBM only) whenever they will fit? After all, integral constants _can_ be managed by the preprocessor. So they can, but not with BOOST_STATIC_CONSTANT as is: BOOST_STATIC_CONSTANT(long long, value = 0ULL); as far as I know there's no way to do different things depending upon the second argument here, but I'd love to be proved wrong (and be very impressed as well!).
We already have BOOST_WORKAROUND. What I can do is provide a BOOST_WORKAROUND that will use an enum if the datatype is not too wide. Simple but effective!
historical note: The reason I brought this up was because Mathias Troyer asked me to remove the BOOST_NO_INCLASS_MEMBER_INITIALIZATION in the config for vacpp version 6. And indeed, vacpp can handle the initialization but does not comply with the DR (so one can argue if BOOST_NO_INCLASS_MEMBER_INITALIZATION should be defined or not). Defining it however caused a problem in the random library however (Mathias can you recall what exactly happened and why).
Yes, the problem was that one of the constants was intialized with a 64-bit constant, and that did not fit into an int. If it is important I could reproduce it tomorrow and report it. Matthias

Matthias Troyer wrote:
Yes, the problem was that one of the constants was intialized with a 64-bit constant, and that did not fit into an int. If it is important I could reproduce it tomorrow and report it.
No need to reproduce the problem. I think this confirms that BOOST_STATIC_CONSTANT's that are not bigger than ints can be BOOST_WORKAROUND'ed with the enum trick until IBM conforms to DR454. So should I implement such a workaround or is this not tought to be a satisfactory solution ?

On Jul 12, 2004, at 10:03 PM, Toon Knapen wrote:
Matthias Troyer wrote:
Yes, the problem was that one of the constants was intialized with a 64-bit constant, and that did not fit into an int. If it is important I could reproduce it tomorrow and report it.
No need to reproduce the problem. I think this confirms that BOOST_STATIC_CONSTANT's that are not bigger than ints can be BOOST_WORKAROUND'ed with the enum trick until IBM conforms to DR454.
How would you do a BOOST_WORKAROUND in a template code where you might not know the value of the static constant? I think that any constant depending on a template parameter will still have to be treated like it is done now. Matthias

Matthias Troyer wrote:
How would you do a BOOST_WORKAROUND in a template code where you might not know the value of the static constant? I think that any constant depending on a template parameter will still have to be treated like it is done now.
Sorry but I fail to understand what you are saying. Anyway what I suggest is to use BOOST_WORKAROUND for implementing the enum-trick wherever BOOST_STATIC_CONSTANT would use the enum-trick in case BOOST_NO_INCLASS_MEMBER_INITIALISATION would have been defined.

Toon Knapen <toon.knapen@fft.be> writes:
Matthias Troyer wrote:
How would you do a BOOST_WORKAROUND in a template code where you might not know the value of the static constant? I think that any constant depending on a template parameter will still have to be treated like it is done now.
Sorry but I fail to understand what you are saying. Anyway what I suggest is to use BOOST_WORKAROUND for implementing the enum-trick wherever BOOST_STATIC_CONSTANT would use the enum-trick in case BOOST_NO_INCLASS_MEMBER_INITIALISATION would have been defined.
Ultimately I think the right answer is to use mpl::integral_c<some_type, some_value> or mpl::bool_<some_value> etc. everywhere as Paul Mensonides suggested. One reason is that it centralizes the out-of-line static member definitions. I'm just not sure how it interacts with all the low-level hacks needed for broken compilers. To get the ::value member (admittedly this is just a convenience) into a metafunction you have to use forwarding via inheritance: template <class T> struct some_trait : mpl::bool_<(some-calculation-using-T)> {}; so it may mean breaking down implementations this way: template <class T> struct some_trait_impl { typedef mpl::bool_<(some-calculation-using-T)> type; }; template <class T> struct some_trait : some_trait_impl<T>::type {}; But I truly believe this is the optimal approach. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
Ultimately I think the right answer is to use
mpl::integral_c<some_type, some_value>
or
mpl::bool_<some_value>
etc.
everywhere as Paul Mensonides suggested. One reason is that it centralizes the out-of-line static member definitions.
I tried this (in the algorithm/string library where I also tested the enum trick for Pavol Droba) and just replaced in algorithm/string/std/string_traits.hpp following lines enum { value = false } ; typedef mpl::bool_< value > type ; with typedef mpl::bool_< false > value ; typedef mpl::bool_< value > type ; and this evidently results in a compilation error. I am not very fluent in mpl but AFAICT this seems like a nice solution but not exactly a drop-in replacement for the current situation.

Toon Knapen wrote:
David Abrahams wrote:
Ultimately I think the right answer is to use mpl::integral_c<some_type, some_value>
or
mpl::bool_<some_value>
etc.
everywhere as Paul Mensonides suggested. One reason is that it centralizes the out-of-line static member definitions.
I tried this (in the algorithm/string library where I also tested the enum trick for Pavol Droba) and just replaced in algorithm/string/std/string_traits.hpp following lines
enum { value = false } ; typedef mpl::bool_< value > type ;
with
typedef mpl::bool_< false > value ; typedef mpl::bool_< value > type ;
and this evidently results in a compilation error.
Doesn't surprise me. You can't just replace an integral constant with a type!
I am not very fluent in mpl but AFAICT this seems like a nice solution but not exactly a drop-in replacement for the current situation.
Not if you do that! I must've failed to make the 2nd half of my posting comprehensible. I don't know how to make it more comprehensible other than to say, "please try what I suggested in the 2nd half of my posting". I guess I can also say that bool_< x > has a nested static bool constant ::value equal to x. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
participants (5)
-
David Abrahams
-
Gennaro Prota
-
John Maddock
-
Matthias Troyer
-
Toon Knapen