Boost logo

Boost :

From: Daniel Krügler (dsp_at_[hidden])
Date: 2004-01-27 05:13:11


Dear boosters,

BOOST_STATIC_CONSTANT is a useful wrapper for compiler
deficiencies regarding ICE's and is one of the most
important corner stones inside boost, especially in the
boost MP library.

Full compliant compilers would translate this macro into:

static const IntegralOrEnumerationType name_of_IC = ICE;

others translate it into:

enum { name_of_IC = ICE };

(This is not exacly true, because "assignment" is part of
the macro, but I dare say, that I have not seen any usage
of this macro, where "assigment" does not translate to
"name_of_IC = ICE", because other expressions should not
result in an overall valid expression).

Enough of the foreword. This thread does deal with possible
linker problems regarding this two-fold definition of
BOOST_STATIC_CONSTANT and if at least one of my following
assumptions regarding the current boost library is true,
this issue should be resolved. If these assumptions are
not true, I apologize honestly for incompletly testing my
hypotheses.

The following short program will examplify the possible
problems on full compliant compilers, which translate
BOOST_STATIC_CONSTANT into a constant static member of
integral or enumeration type:

#include <boost/mpl/vector.hpp>
#include <boost/mpl/size.hpp>

void foo(const long&)
{
}

int main()
{
   typedef boost::mpl::vector<char, double> MyTypeContainer;
   typedef boost::mpl::size<MyTypeContainer> MPSizeType;

   foo(MPSizeType::value);
}

The reason for the linker error (on VC7.1 and mingw with the
gcc version 3.2, both with the boost_1_30_0 library) is clear:

Due to missing definitions of the static class member
boost::mpl::size<>::value and the fact, that foo uses the address
of this very beast. Please note, that the exact matching of the
type of boost::mpl::size<>::value with the foo function signature
is necessary to simulate this behaviour (otherwise a temporary
is used).

- Assumption one: Boost does not provide the definitions of
potential static constants hidden by the BOOST_STATIC_CONSTANT
definition (I used only the headers of the library, so my potential
testing bug would be that I had to include the corresponding
translation units of boost providing the constant's definitions,
but sorry - I did not find them!).
As I said: If this assumption is false, please blame me straight
for incomplete testing and for trying to spread bad rumors on this
(really!) great library.

- Assumption two: Even if Boost does provide these definitions,
there may occur problems due to the VC7.1 flags /Za and /Ze (aka
disabling and enabling language extensions), which I will explain
in the following. The same point applies as to assumptions one, if
I did incomplete testing or testing with rather old boost libraries.

The nasty thing concerning the /Ze flag is that it effectively does
not "extend" the language in every case. A small testing case is the
following program:

a.h: -------------------------
#ifndef A_H_INC
#define A_H_INC
struct A
{
   static const int val = 42; // Declaration of a static member variable
};
#endif
-------------------------

a.cpp --------------------
#include "a.h"
const int A::val; // Definition might be needed, if the program accesses
                   // the adress of A::val
-------------------------

main.cpp --------------------
#include "a.h"
int main()
{
}
-------------------------

Although this is a C++ Standard compliant program, it will not
successfully link with the /Ze flag enabled, which is to my opion a real
compiler bug (which I already posted to m.p.v.language, but got no
reasonable response yet). The obtained error message is:

error LNK2005: "private: static int const A::val" (?val_at_A@@0HB) already
defined in a.obj
error LNK2005: "private: static int const A::val" (?val_at_A@@0HB) already
defined in main.obj

Question: Is this special deficiency of the VC7.1 compiler taken account
in the current boost library? I think, it is impossible to demand, that
users are enforced to use either only /Ze or only /Za, because each of
these choices has some considerable drawbacks (at least on Windows
systems...)

Thank you for listening and apologies for possibly wrong bug reports,

Daniel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk