[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

const static member

Chameleon

11/3/2008 8:34:00 PM

The following code produces strange errors in mingw.
Is a C++ problem or compiler problem?
----------------------------
#include <list>

class A
{
static const int B = 0;
std::list<int> lst;
void calc();
};


void A::calc()
{
lst.push_back(B); // produces 'undefined reference to A::B'
int a = B;
lst.push_back(a); // its ...ok!
}

int main() { return 0; }
----------------------------
3 Answers

sean_in_raleigh

11/3/2008 9:16:00 PM

0

On Nov 3, 3:34 pm, Chameleon <cham_...@hotmail.com> wrote:
> The following code produces strange errors in mingw.
> Is a C++ problem or compiler problem?
> ----------------------------
> #include <list>
>
> class A
> {
> static const int B = 0;

Sadly, the above line does not define
storage for B, but only declares it.

You also need this defined somewhere:

const int A::B;

I believe it's just working for you in the
second case because it's getting optimized
away. Compiler bug, I guess.

Sean

Andrey Tarasevich

11/3/2008 10:32:00 PM

0

Chameleon wrote:
> The following code produces strange errors in mingw.
> Is a C++ problem or compiler problem?

It is a problem with your code. In the C++98 specification all static
members of the class used in the program, have to be explicitly defined.
You failed to define the member, which is why from C++98 point of view
your code is ill-formed in _both_ contexts.

The revised C++ standard is more elaborate in this respect. Your
compiler's behavior is consistent with the revised specification.

> ----------------------------
> #include <list>
>
> class A
> {
> static const int B = 0;
> std::list<int> lst;
> void calc();
> };
>
>
> void A::calc()
> {
> lst.push_back(B); // produces 'undefined reference to A::B'

'push_back' method accepts its parameters by constant reference and the
parameter and argument type matches exactly in this case, which means
that in the above context the reference is bound directly to the lvalue
'A::B'. This requires a definition of 'A::B' object. You forgot to
provide one. This is why you get an error.

> int a = B;
> lst.push_back(a); // its ...ok!
> }

In this context the value of 'B' can be used as an rvalue, an integral
constant expression. There's no requirement to define 'A::B' for this
particular context.

--
Best regards,
Andrey Tarasevich

James Kanze

11/3/2008 10:51:00 PM

0

On Nov 3, 10:15 pm, sean_in_rale...@yahoo.com wrote:
> On Nov 3, 3:34 pm, Chameleon <cham_...@hotmail.com> wrote:

> > The following code produces strange errors in mingw. Is a
> > C++ problem or compiler problem?

Your problem. The code is not legal C++.

> > ----------------------------
> > #include <list>

> > class A
> > {
> >     static const int B = 0;

> Sadly, the above line does not define storage for B, but only
> declares it.

> You also need this defined somewhere:

>   const int A::B;

> I believe it's just working for you in the second case because
> it's getting optimized away.  Compiler bug, I guess.

No compiler bug. Not defining a variable which has been used is
undefined behavior, so anything the compiler does with it is
fine. In practice, given a declaration which can be used as an
integral constant expression, most compilers will only require
the definition if it is used in a context where there was not an
immediate lvalue to rvalue conversion. When you use it to
initialize another int, there is an immediate lvalue to rvalue
conversion; list<int>::push_back, on the other hand, takes a
reference, so there is no lvalue to rvalue conversion.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34