470,636 Members | 1,582 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,636 developers. It's quick & easy.

const static initialization in Visual Studio

t
Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.

I tried it using Visual C++ 2005 Express edition and get this error:

1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj

Is this one of those things that vary by compiler? Is what Lippman
said from Standard C++?

My code is basically like this (lots of stuff omitted):
// Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H

class Account
{
static const int period = 30;
};

#endif

// Account.cpp

#include "Account.h"

const int Account::period;

// Account Main.cpp

#include "Account.h"

int main()
{
Account acc;
}

Sep 19 '07 #1
9 6361
t wrote:
Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.

I tried it using Visual C++ 2005 Express edition and get this error:

1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj

Is this one of those things that vary by compiler? Is what Lippman
said from Standard C++?
Yes. But it's only required for the variables that are used as
l-values (like when taking their address or binding a reference to
them). Try dropping the out-of-class definition since you're not
using it anyway.
My code is basically like this (lots of stuff omitted):
// Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H

class Account
{
static const int period = 30;
};

#endif

// Account.cpp

#include "Account.h"

const int Account::period;

// Account Main.cpp

#include "Account.h"

int main()
{
Account acc;
}
Can just be a bug in VC++. Ask in 'microsoft.public.vc.language'

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 19 '07 #2
Victor Bazarov wrote:
t wrote:
>Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.

I tried it using Visual C++ 2005 Express edition and get this error:

1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj

Is this one of those things that vary by compiler? Is what Lippman
said from Standard C++?

Yes. But it's only required for the variables that are used as
l-values (like when taking their address or binding a reference to
Are you sure? where in standard mention this.
Comeau online happily accept this:
struct A
{
static const int value = 10;
};

//const int A::value; // not required by Comeau

int main()
{
int const* pi = &A::value;
}

I thought it was just like

const int SOME_CONST = 10;
int const* pi = &SOME_CONST;

the compiler automatically allocates memory for this const variable,
since we take its address.

them). Try dropping the out-of-class definition since you're not
using it anyway.


--
Thanks
Barry
Sep 20 '07 #3
t wrote:
Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.

I tried it using Visual C++ 2005 Express edition and get this error:

1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj
This is a compiler bug,
As I use VC++2005, it produces a compile error
"redefinition; multiple initialization"

--
Thanks
Barry
Sep 20 '07 #4
Barry wrote:
Victor Bazarov wrote:
>t wrote:
>>Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.

I tried it using Visual C++ 2005 Express edition and get this error:

1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj

Is this one of those things that vary by compiler? Is what Lippman
said from Standard C++?

Yes. But it's only required for the variables that are used as
l-values (like when taking their address or binding a reference to

Are you sure? where in standard mention this.
Do you have a copy of the Standard? Then use it. If not, get one.
Comeau online happily accept this:
struct A
{
static const int value = 10;
};

//const int A::value; // not required by Comeau

int main()
{
int const* pi = &A::value;
}
Comeau online does not *link*, so if the definition is missing,
you would never know.
I thought it was just like

const int SOME_CONST = 10;
int const* pi = &SOME_CONST;

the compiler automatically allocates memory for this const variable,
since we take its address.
Yes, but here you have _defined_ the 'SOME_CONST', not just declared
it in a class definition.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 20 '07 #5
Victor Bazarov wrote:
Barry wrote:
>Victor Bazarov wrote:
>>t wrote:
Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.

I tried it using Visual C++ 2005 Express edition and get this error:

1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj

Is this one of those things that vary by compiler? Is what Lippman
said from Standard C++?
Yes. But it's only required for the variables that are used as
l-values (like when taking their address or binding a reference to
Are you sure? where in standard mention this.

Do you have a copy of the Standard? Then use it. If not, get one.
Well, I tried, but couldn't locate the content.
:-)
--
Thanks
Barry
Sep 20 '07 #6
On Sep 19, 9:15 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
t wrote:
Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.
I tried it using Visual C++ 2005 Express edition and get this error:
1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj
Is this one of those things that vary by compiler? Is what Lippman
said from Standard C++?
Yes. But it's only required for the variables that are used as
l-values (like when taking their address or binding a reference to
them).
According to my copy of the C++ 1998 version of the standard,
it's required, period. The latest draft makes an exception for
variables which qualify for use in an integral constant
expression, and for which all uses result in an immediate lvalue
to rvalue conversion, but that's something which has been added.

Of course, failing to provide the definition is undefined
behavior, so it might work anyway. But since it's never wrong
to provide it, why not?
Try dropping the out-of-class definition since you're not
using it anyway.
My code is basically like this (lots of stuff omitted):
// Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H
class Account
{
static const int period = 30;
};
#endif
// Account.cpp
#include "Account.h"
const int Account::period;
// Account Main.cpp
#include "Account.h"
int main()
{
Account acc;
}
Can just be a bug in VC++. Ask in 'microsoft.public.vc.language'
This is very definitly a serious bug in the compiler. If he
doesn't define the variable, VC++ compiles the code, *but* gives
Account::period different addresses in different compilation
units. (And of course, if you do take the address, most other
compilers will require the definition.)

In sum, you still cannot use this form of initializer in
portable code, but are stuck with the earlier use of enum, e.g.:

class Account
{
enum { period = 30 } ;
} ;

The type won't be right, but at least it will work portably.

--
James Kanze (GABI Software) email:ja*********@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

Sep 20 '07 #7
On Sep 20, 6:11 am, Barry <dhb2...@gmail.comwrote:
Victor Bazarov wrote:
Barry wrote:
Victor Bazarov wrote:
t wrote:
Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.
>>I tried it using Visual C++ 2005 Express edition and get this error:
>>1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj
>>Is this one of those things that vary by compiler? Is what Lippman
said from Standard C++?
Yes. But it's only required for the variables that are used as
l-values (like when taking their address or binding a reference to
Are you sure? where in standard mention this.
Do you have a copy of the Standard? Then use it. If not, get one.
Well, I tried, but couldn't locate the content.
:-)
§3.2, paragraphes 2 and 3. The 1998 version of the standard
says:

An expression is potentially evaluated unless either it is
the operand of the sizeof operator, or it is the operand of
the typeid operator and does not designate an lvalue of
polymorphic class types. An object [Account::period is an
object] or non-overloaded function is *used* if its name
appears in a potentially-evaluated expression. [Lot's of
other things are used whenever...]

Every program shall contain exactly one definition of every
non-inline function or object that is used in that program;
no diagnostic required.

There isn't even the exception that Victor mentionned; if you
*use* Account::period, you must define it in exactly one
translation unit. (The declaration in the class definition is
just that, a declaration. See §3.1/2: "A declaration is a
definition unless [...], it declares a static data member in a
class declaration.)

The current draft is similar, but has added text in §3.2 to the
effect that if the object qualifies for use in an integral
constant expression, and all of its uses involve an immediate
lvalue to rvalue conversion, then no definition is necessary.
(Basically, the exception to the rule that Victor mentionned.)

(And yes, it is sometimes difficult to find the correct location
in the standard.)

--
James Kanze (GABI Software) email:ja*********@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

Sep 20 '07 #8
In article <11*********************@22g2000hsm.googlegroups.c om>,
James Kanze <ja*********@gmail.comwrote:
>On Sep 19, 9:15 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>t wrote:
Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.
I tried it using Visual C++ 2005 Express edition and get this error:
1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj
Is this one of those things that vary by compiler? Is what Lippman
said from Standard C++?
>Yes. But it's only required for the variables that are used as
l-values (like when taking their address or binding a reference to
them).

According to my copy of the C++ 1998 version of the standard,
it's required, period. The latest draft makes an exception for
variables which qualify for use in an integral constant
expression, and for which all uses result in an immediate lvalue
to rvalue conversion, but that's something which has been added.
This is one of those "funny ones". At least as I recall it,
the committee voted for (at least) the sentiment of the words in the
latest draft to have originally been included in C++98, however the
words got lost in some shuffle. So it was basically a typo
defect in the standard, although, clearly, the words themselves
are absent in the C++98 text, implying that it's fair to argue that
the behavior was not in C++98 if one take it literally, which one
usually should.
--
Greg Comeau / 4.3.9 with C++0xisms now in beta!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Sep 20 '07 #9
On Sep 20, 7:17 pm, com...@panix.com (Greg Comeau) wrote:
In article <1190290249.900939.43...@22g2000hsm.googlegroups.c om>,
James Kanze <james.ka...@gmail.comwrote:
On Sep 19, 9:15 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
t wrote:
Lippman's C++ Primer says that if you initialize a const static data
member in a class, you still need to define the member outside the
class but without an initializer.
I tried it using Visual C++ 2005 Express edition and get this error:
1>Account.obj : error LNK2005: "private: static int const
Account::period" (?period@Account@@0HB) already defined in Account
Main.obj
Is this one of those things that vary by compiler? Is what Lippman
said from Standard C++?
Yes. But it's only required for the variables that are used as
l-values (like when taking their address or binding a reference to
them).
According to my copy of the C++ 1998 version of the standard,
it's required, period. The latest draft makes an exception for
variables which qualify for use in an integral constant
expression, and for which all uses result in an immediate lvalue
to rvalue conversion, but that's something which has been added.
This is one of those "funny ones". At least as I recall it,
the committee voted for (at least) the sentiment of the words in the
latest draft to have originally been included in C++98, however the
words got lost in some shuffle. So it was basically a typo
defect in the standard, although, clearly, the words themselves
are absent in the C++98 text, implying that it's fair to argue that
the behavior was not in C++98 if one take it literally, which one
usually should.
Well, it's not really a problem, since 1) failing to define the
variable is undefined behavior, and it actually works with all
existing compilers, if the conditions in the latest draft apply,
and 2) such constants tend to end up being used in lvalue
contexts anyway (e.g. by being passed to a template function
which takes a T const&), so it's just good practice to
systematically define then, regardless. (Personally, because of
2, I'm quite happy with the words in the current standard. They
have the advantage of being simpler, and easier to understand,
and the added freedom is not one I'll ever use.)

--
James Kanze (GABI Software) email:ja*********@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

Sep 21 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Fred Zwarts | last post: by
13 posts views Thread by Amadeus W. M. | last post: by
7 posts views Thread by Spoon | last post: by
18 posts views Thread by mati | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.