Click to See Complete Forum and Search --> : static (const) data members


mcn
May 29th, 2002, 06:43 AM
trying to avoid using of Macros for declarations of the form

char u[MAXLEN];

because many old code in our departement was written before gcc was able to handle namespaces correctly, we used classes with static data members/methods instead. now we tried to port the following code to be used with VC++ 6.0

// a.hh
class A {
private:
A() {}
virtual ~A() {}

public:
static const int a;
};

// a.cc
#include "a.h"

const int A::a = 7;

b.hh
class B {
public:
B();
virtual ~B() {}

};

// b.cc
#include "a.h"
#include "b.h"

B::B()
{
char u[A::a]; // error will occur here!!!
std::cerr << "A::a is " << A::a << std::endl;
std::cerr << "sizeof(u) is " << sizeof(u) << std::endl;
}

// test.cc
#include "b.h"

int main(int argc, char* argv[])
{
B b;
return 0;
}


things which works well with gcc yield the following the compiler errors using VC:

error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'u' : unknown size
error C2070: illegal sizeof operand

is this behaviour covered by the standard. i know that problems occur during dynamic initialization of A::a at runtime and its value may be undefined or 0 (statically initialized) but i never saw problems during compiletime.

mark

AlanGRutter
May 29th, 2002, 08:02 AM
All of your errors are because you cannot use A::a as the dimension for your array.

Although A::a is a static const class member and is instantiated in the cpp properly, the value is only set up at run time as part of the global initialisation proceudre of the module.

The compiler doesn't interpret the following to be compile time constant.

const int A::a = 7;

You can only dimension arrays (without using new) using compiel time constants. Yours is a run-time constant. This is covered in the standard and should IMHO fail to compile on any compiler.

Regards
Alan.

mcn
May 29th, 2002, 11:28 AM
ok, but the same construction with

char u[B::b]

compiles without errors.

btw.: have you ever tried

class A {
// ...
static const int a = 4;
// ...
};

with VC++?

mark

AlanGRutter
May 30th, 2002, 03:37 AM
You have no member b in class B - at least not that I can see from your posting. It shouldn't compile for the same reasons - it requires the compiler to know the value at compile time, which isn't possible.

You can only do that kind of thing if you have an enum in the class which is the normal way of doing what you're trying to do in your second question.


class A
{
....
enum { a = 4 };
....
};

<return type> A::somefunction(...)
{
char u[A::a]; // now legal
}

According to revisions that were made several years ago when the standards committee discussed static class member constants, your declaration is now legal. However, VC++ 6.0 and below is not compliant with this change. You have to do the following I'm afraid


class A
{
....
static const int a;
....
};
const int A::a = 4;

I've no idea if they have fixed this in VS .NET - hopefully they have.

Regards
Alan