I have a strange gcc 4.7 problem with c++11 enabled :
When I want to compile this:
constexpr unsigned int getDim(const int e){
return (e==1)? A::Set::Dimension :
(
(e==2)? B::Set::Dimension :
(
(e==3)? C::Set::Dimension :
(
+D::Set::Dimension
)
)
);
}
where for each struct A,B,C,D
a typedef for Set
is defined where the related Set has an int Dimension
, for example
struct SetOne{
static const int Dimension = 1;
}
struct A{
typedef SetOne Set;
}
If I don't use the unary +
infront of D::Set::Dimension
the linker fails complaining about undefined references to SetOne::Dimension.
Is this the same problem as: Undefined reference to static class member
I cannot give a MWE as the problem vanished for a simple example with one .cpp file. ? (but all definitions are for A,B,C,D are in one header file)
Does anybody have a clue what might go wrong here? This is unintuitiv :-)
Observation 2:
If one replaces: +D::Set::Dimension
with 0, it compiles fine, but why the hack the other statements as A::Set::Dimension
do not rise the same linking error?
In the expression you are building, the ternary expression is yielding an lvalue, which causes the odr-use of the static constant. The One Definition Rule requires that all static members that are odr-used are defined, so you need to provide a definition (in a single translation unit).
So why does the problem go away with the unary +?
The unary +
does not cause the odr-use of the static member, it only requires an rvalue, and the result of it is another rvalue. That cascades out through the conditional operators as once one of the two arguments is an rvalue the result of the expression will also be an rvalue. The end result is that the single +
has the effect of forcing the lvalue-to-rvalue conversion of all of the static consts used in the function and removes the odr-uses.
If one replaces: +D::Set::Dimension with 0, it compiles fine
Again, 0 is an rvalue, and it will have the same effect as the unary +
described above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With