static const member of class

41 просмотр
Перейти к первому непрочитанному сообщению

Bjarke Dahl Ebert

не прочитано,
26 окт. 1999 г., 03:00:0026.10.1999
I thought that a class was allowed to have an "initialized" static const
member.

What I want is

class Foo
{
// ...
public:
static const int num = 20;
};

This compiles fine with Borland C++Builder 3.0.
However, Microsoft VC++ version 6 tells me:

foo.h(60) : error C2258: illegal pure syntax, must be '= 0'

And browsing the documentation reveals that

"Member declarators cannot contain initializers. Supplying an
initializer produces an error message as illustrated in the following
code:

class CantInit
{
public:
long l = 7; // Error: attempt to initialize
// class member.
static int i = 9; // Error: must be defined and initialized
outside of class declaration.
};
"

But I don't want to define the value outside of the class. I want the
constant to be as effectively inlined as if I used a #define. I know
that #define is evil, but that is what I have to use now, because MSVC
won't eat my code :-(. A worse situation would be if I had to read 'num'
in a template, i.e. "T::num" - then a #define would be even more the
wrong solution.

Am I right in assuming that MSVC doesn't implement the ISO C++ standard
right?

Kind regards
Bjarke

--
Bjarke Dahl Ebert, M.Sc Cryptomathic A/S
Senior Systems Engineer Klostergade 28, 1.
Phone: +45 8613 9020 DK-8000 Århus, Denmark
Fax: +45 8620 2975 http://www.cryptomathic.dk/
http://www.cryptomathic.dk/bde/

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]


ash...@my-deja.com

не прочитано,
27 окт. 1999 г., 03:00:0027.10.1999
The Microsoft VC++ 6.0 does not comply with the standard on this one
yet.
You still need to initialize a static const object at global scope.

What you might do is use an enum.

class Foo {
enum {num = 20};
char CharArray [num];

};

And, then you use the enum as a static constant.

Ash

Bjarke Dahl Ebert wrote:
>
> I thought that a class was allowed to have an "initialized" static const
> member.
>
>

> But I don't want to define the value outside of the class. I want the
> constant to be as effectively inlined as if I used a #define. I know
> that #define is evil, but that is what I have to use now, because MSVC
> won't eat my code :-(. A worse situation would be if I had to read 'num'
> in a template, i.e. "T::num" - then a #define would be even more the
> wrong solution.
>
> Am I right in assuming that MSVC doesn't implement the ISO C++ standard
> right?

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Albela Kela

не прочитано,
27 окт. 1999 г., 03:00:0027.10.1999
This is a known bug in MSVC6.0. The ability to declare const static members
is a recent addition to the standard.

If you must use MSVC or other older compilers, use enums to get the same
effect.

> I thought that a class was allowed to have an "initialized" static const
> member.

{ Unreferenced quoting removed, please edit your posts. -mod/jep }

Ron Natalie

не прочитано,
27 окт. 1999 г., 03:00:0027.10.1999

Bjarke Dahl Ebert wrote:

> However, Microsoft VC++ version 6 tells me:
>
> foo.h(60) : error C2258: illegal pure syntax, must be '= 0'
>
> And browsing the documentation reveals that

It's a known bug in VC++. Just move the initialization outside the
class.

class Foo {
public:
static const int num;
};

static const int Foo::num = 20;

Michiel Salters

не прочитано,
27 окт. 1999 г., 03:00:0027.10.1999
Bjarke Dahl Ebert wrote:

> I thought that a class was allowed to have an "initialized" static const
> member.

Yes (in ISO C++)

> What I want is

> class Foo
> {
> // ...
> public:
> static const int num = 20;
> };

Perfecly fine.

> This compiles fine with Borland C++Builder 3.0.

> However, Microsoft VC++ version 6 tells me:

> foo.h(60) : error C2258: illegal pure syntax, must be '= 0'

> And browsing the documentation reveals that

> "Member declarators cannot contain initializers. Supplying an


> initializer produces an error message as illustrated in the following
> code:

> class CantInit
> {
> public:
> long l = 7; // Error: attempt to initialize
> // class member.
> static int i = 9; // Error: must be defined and initialized
> outside of class declaration.
> };
> "

That's microsoft at work for you.

> But I don't want to define the value outside of the class. I want the
> constant to be as effectively inlined as if I used a #define. I know
> that #define is evil, but that is what I have to use now, because MSVC
> won't eat my code :-(. A worse situation would be if I had to read 'num'
> in a template, i.e. "T::num" - then a #define would be even more the
> wrong solution.

You're reading too much into this. Constants are alwyas "inlined".
The alternative required by MS is to put the initializer in an
implementation file, but that does not cause any run-time overhead
whatsoever. It's only the linker that must look for this constant.
Doing this creates portable code - other compilers can handle this
too. #defines are still bad.

There is an alternative: enum.


class Foo
{
enum { num = 20 }
}

keeps everything in the header file - but this works only for integers.


> Am I right in assuming that MSVC doesn't implement the ISO C++ standard
> right?

Yes - but that's not an excuse to use #define.

> Kind regards
> Bjarke

Michiel Salters

rado42

не прочитано,
27 окт. 1999 г., 03:00:0027.10.1999
In article <3815BB15...@cryptomathic.dk>,

Bjarke Dahl Ebert <b...@cryptomathic.dk> wrote:
> I thought that a class was allowed to have an "initialized" static
const
> member.
>
> What I want is
>
> class Foo
> {
> // ...
> public:
> static const int num = 20;
> };
>
> This compiles fine with Borland C++Builder 3.0.
> However, Microsoft VC++ version 6 tells me:
>
> foo.h(60) : error C2258: illegal pure syntax, must be '= 0'
>
> And browsing the documentation reveals that
>
> "Member declarators cannot contain initializers. Supplying an
> initializer produces an error message as illustrated in the following
> code:
>
> class CantInit
> {
> public:
> long l = 7; // Error: attempt to initialize
> // class member.
> static int i = 9; // Error: must be defined and initialized
> outside of class declaration.
> };
> "
>
> But I don't want to define the value outside of the class. I want the
> constant to be as effectively inlined as if I used a #define. I know
> that #define is evil, but that is what I have to use now, because MSVC
> won't eat my code :-(. A worse situation would be if I had to
read 'num'
> in a template, i.e. "T::num" - then a #define would be even more the
> wrong solution.
>
> Am I right in assuming that MSVC doesn't implement the ISO C++
standard
> right?

No you're not - as far as this problem is concerned; otherwise yes.

A solution for your problem is:

class Foo
{
// ...
public:

enum { num = 20 };
};


--
rado
http://members.tripod.com/~radosoft


Sent via Deja.com http://www.deja.com/
Before you buy.

TiTi

не прочитано,
28 окт. 1999 г., 03:00:0028.10.1999
Should be like this:


// header file
class Foo
{
public:
static const int num;
};

// implementation file


const int Foo::num = 20;


TiTi

> What I want is
>
> class Foo
> {
> // ...
> public:
> static const int num = 20;
> };

Rick Ratliff

не прочитано,
28 окт. 1999 г., 03:00:0028.10.1999

I would initialize this in the .cpp file unless it is needed in the .h file

// Foo.cpp

const int
Foo::num(20);

I believe this to be better style, because it hides the value of num in the
implementation file. After all, you're defining a public const to be used
instead of the literal 20.

--
Rick Ratliff -- Senior Software Architect
A.B. Watley Group Inc. -- http://www.abwatley.com
1021 S. Central Expressway, Suite 200
Allen, Texas 75013-2790

Bjarke Dahl Ebert wrote in message <3815BB15...@cryptomathic.dk>...


>I thought that a class was allowed to have an "initialized" static const
>member.
>

>What I want is
>
>class Foo
>{
>// ...
>public:
> static const int num = 20;
>};
>

>This compiles fine with Borland C++Builder 3.0.
>However, Microsoft VC++ version 6 tells me:
>
> foo.h(60) : error C2258: illegal pure syntax, must be '= 0'
>
>And browsing the documentation reveals that
>
>"Member declarators cannot contain initializers. Supplying an
>initializer produces an error message as illustrated in the following
>code:
>
>class CantInit
>{
>public:
> long l = 7; // Error: attempt to initialize
> // class member.
> static int i = 9; // Error: must be defined and initialized
> outside of class declaration.
>};
>"
>
>But I don't want to define the value outside of the class. I want the
>constant to be as effectively inlined as if I used a #define. I know
>that #define is evil, but that is what I have to use now, because MSVC
>won't eat my code :-(. A worse situation would be if I had to read 'num'
>in a template, i.e. "T::num" - then a #define would be even more the
>wrong solution.
>
>Am I right in assuming that MSVC doesn't implement the ISO C++ standard
>right?

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Paul Whitehead

не прочитано,
29 окт. 1999 г., 03:00:0029.10.1999
Purely out of interest here, no-one seems to have taken a look at
build-time dependencies re: static const member of class.

Placing an initialised static const int/enum value in a class header
file means that should you ever wish to change the value then all files
with a dependency on that header will get re-compiled. Placing a static
const int initialiser in the class file means that only that one class
file will need to be re-compiled should the value change. Unfortunately,
the anonymous enum assignment can only take place in the header file so
you're stuck with the dependencies problem if you go for the enum
assignment (as well as being stuck with int-only values).

This is why I prefer to declare a static const int (or long or whatever)
in the class header but initialise it in the class implementation file.
Of course, if build times aren't a problem for you then you won't gain
much but I think it's a point worth bearing in mind...

Paul.

Michiel Salters wrote:


>
> Bjarke Dahl Ebert wrote:
>
> > I thought that a class was allowed to have an "initialized" static const
> > member.
>

> Yes (in ISO C++)


>
> > What I want is
>
> > class Foo
> > {
> > // ...
> > public:
> > static const int num = 20;
> > };
>

> Perfecly fine.
>
[snipped]


> There is an alternative: enum.
>
> class Foo
> {
> enum { num = 20 }
> }
>
> keeps everything in the header file - but this works only for integers.

> > Am I right in assuming that MSVC doesn't implement the ISO C++ standard
> > right?
>

> Yes - but that's not an excuse to use #define.
>
> > Kind regards
> > Bjarke
>
> Michiel Salters
>

Paul Whitehead

не прочитано,
29 окт. 1999 г., 03:00:0029.10.1999
TiTi wrote:
>
> Should be like this:
>
> // header file
> class Foo
> {
> public:

> static const int num;
> };
>
> // implementation file
> const int Foo::num = 20;
>
> TiTi
>
> > What I want is
> >
> > class Foo
> > {
> > // ...
> > public:
> > static const int num = 20;
> > };

hmmm... both seem o.k. to me (although read my previous post about build
dependencies when using assignment in header). The fact that Microsoft
hasn't yet gotten round to catering for it doesn't mean that it is in
any way invalid C++ - it just means that Microsoft hasn't yet gotten
round to catering for it...

BTW: is Microsoft the only compiler that *can't* handle static const
assignment in headers or have I just been lucky with other C++
compilers?

Paul.

Greg Comeau

не прочитано,
29 окт. 1999 г., 03:00:0029.10.1999
In article <7v6to6$4ib$1...@holly.prod.itd.earthlink.net> "Rick Ratliff" <ri...@ratliff.org> writes:
>I would initialize this in the .cpp file unless it is needed in the .h file
>
>// Foo.cpp
>
>const int
>Foo::num(20);
>
>I believe this to be better style, because it hides the value of num in the
>implementation file. After all, you're defining a public const to be used
>instead of the literal 20.

Hiding is great and has its place, but has to be for the right reasons.
For instance, consider:

// not in a .h file
int x[num];

- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C/C++ 4.2.38 -- NOTE 4.2.42 BETAS NOW AVAILABLE
Email: com...@comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
*** WEB: http://www.comeaucomputing.com ***

TT

не прочитано,
30 окт. 1999 г., 03:00:0030.10.1999
> BTW: is Microsoft the only compiler that *can't* handle static const
> assignment in headers or have I just been lucky with other C++
> compilers?


It (VC++6) can't handle any assignements in a class declaration, other than
= 0 for pure virtual methods. It has nothing to do with the const or the
static keyword. Following code fragments do not compile under VC++6.

class A
{
public:
static const int x = 20;
};

class A
{
public:
const int x = 20;
};

class A
{
public:
int x = 20;
};

class A
{
public:
static int x = 20;
};

And I don't see why it should. Is it in the standard?


TiTi

Oliver Hoehle

не прочитано,
30 окт. 1999 г., 03:00:0030.10.1999
You have to declare the variable in the header and define it in the
.cpp-file like this:

class foo {
statis const int num;
};

...

const int foo::num = 20;

have fun...
Oliver

Bjarke Dahl Ebert schrieb:

> I thought that a class was allowed to have an "initialized" static const
> member.
>

> What I want is
>
> class Foo
> {
> // ...
> public:
> static const int num = 20;
> };
>

> This compiles fine with Borland C++Builder 3.0.
> However, Microsoft VC++ version 6 tells me:
>
> foo.h(60) : error C2258: illegal pure syntax, must be '= 0'
>
> And browsing the documentation reveals that
>
> "Member declarators cannot contain initializers. Supplying an
> initializer produces an error message as illustrated in the following
> code:
>
> class CantInit
> {
> public:
> long l = 7; // Error: attempt to initialize
> // class member.
> static int i = 9; // Error: must be defined and initialized
> outside of class declaration.
> };
> "
>
> But I don't want to define the value outside of the class. I want the
> constant to be as effectively inlined as if I used a #define. I know
> that #define is evil, but that is what I have to use now, because MSVC
> won't eat my code :-(. A worse situation would be if I had to read 'num'
> in a template, i.e. "T::num" - then a #define would be even more the
> wrong solution.
>

> Am I right in assuming that MSVC doesn't implement the ISO C++ standard
> right?

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

John Potter

не прочитано,
31 окт. 1999 г., 02:00:0031.10.1999
On 30 Oct 1999 05:24:48 -0400, "TT" <TJu...@mad.dog.com> wrote:

: It (VC++6) can't handle any assignements in a class declaration, other than


: = 0 for pure virtual methods. It has nothing to do with the const or the
: static keyword.

You have no understanding of the problem. It has everything to do
with static and const and integral.

: Following code fragments do not compile under VC++6.


:
: class A
: {
: public:
: static const int x = 20;

This is valid standard C++ and should be accepted.

: const int x = 20;

This is invalid standard C++ and should be rejected.

: int x = 20;

This is invalid standard C++ and should be rejected.

: static int x = 20;

This is invalid standard C++ and should be rejected.

static const double = 3.14;

This is invalid standard C++ and should be rejected.

: };
:
: And I don't see why it should. Is it in the standard?

Yes.

John

TiTi

не прочитано,
2 нояб. 1999 г., 03:00:0002.11.1999
Indeed, take this example from the standard (3.4.3, qualified name lookup,
p60):


class C
{
class X{};
static const int number = 50;
static X arr[number];
};

Is well-formed.

TiTi

> : And I don't see why it should. Is it in the standard?
>
> Yes.

ash...@my-deja.com

не прочитано,
9 нояб. 1999 г., 03:00:0009.11.1999
Another interesting implication is that the const object can be changed
depending on which translation unit it is used.
Like for example I have a connection class which multiplexes the
connections and there is a const object for the number of connections.
Then depending on the OS, hardware I can include different files at
compile time and assign different values to the number of connections
object.
This is just an example and please take it for it is worth.

Paul Whitehead wrote:
>
> Purely out of interest here, no-one seems to have taken a look at
> build-time dependencies re: static const member of class.

I like your build times comment. It certainlt is more and more useful
as code becomes larger to support more functionality.

ash

Ответить всем
Написать сообщение автору
Переслать
0 новых сообщений