const static member

C

Chameleon

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; }
----------------------------
 
S

sean_in_raleigh

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
 
A

Andrey Tarasevich

Chameleon said:
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.
 
J

James Kanze

Your problem. The code is not legal C++.
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top