[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.c++

static/nonstatic data member declaration/definition

Jeff

9/29/2008 2:40:00 AM

My understanding is that if you write

class X {
int y;
static int z;
};

then you've defined (and declared) X and y, but you have only declared
(and not defined) z. If you'd like to actually define z, you also
need to add

int X::z;

Can anybody tell me the reason that the language was designed to be
like this? It seems it would be simpler if z were defined in the same
way as y, so presumably there's some good reason.
18 Answers

Jeff Schwab

9/29/2008 2:52:00 AM

0

Jeffrey wrote:
> My understanding is that if you write
>
> class X {
> int y;
> static int z;
> };
>
> then you've defined (and declared) X and y, but you have only declared
> (and not defined) z. If you'd like to actually define z, you also
> need to add
>
> int X::z;
>
> Can anybody tell me the reason that the language was designed to be
> like this? It seems it would be simpler if z were defined in the same
> way as y, so presumably there's some good reason.

Because you only want the definition to be in one translation unit, or
you'll get link errors. The declarations, on the other hand, should be
in every translation unit that needs access to them.

Jeff Schwab

9/29/2008 2:54:00 AM

0

Jeff Schwab wrote:
> Jeffrey wrote:
>> My understanding is that if you write
>>
>> class X {
>> int y;
>> static int z;
>> };
>>
>> then you've defined (and declared) X and y, but you have only declared
>> (and not defined) z. If you'd like to actually define z, you also
>> need to add
>>
>> int X::z;
>>
>> Can anybody tell me the reason that the language was designed to be
>> like this? It seems it would be simpler if z were defined in the same
>> way as y, so presumably there's some good reason.
>
> Because you only want the definition to be in one translation unit, or
> you'll get link errors. The declarations, on the other hand, should be
> in every translation unit that needs access to them.

Btw, there's a loop-hole for class templates. Static member variables
of class templates (not including explicit specializations) can live
right up in the header file, along with the rest of the corresponding
template definition.

Rolf Magnus

9/29/2008 3:24:00 AM

0

Jeffrey wrote:

> My understanding is that if you write
>
> class X {
> int y;
> static int z;
> };
>
> then you've defined (and declared) X and y, but you have only declared
> (and not defined) z. If you'd like to actually define z, you also
> need to add
>
> int X::z;
>
> Can anybody tell me the reason that the language was designed to be
> like this?

Well, whenever you instantiate the class, you get the member y. But z is
supposed to exist exactly noce, not once for every object.

James Kanze

9/29/2008 8:24:00 AM

0

On Sep 29, 4:40 am, Jeffrey <jkar...@gmail.com> wrote:
> My understanding is that if you write

> class X {
> int y;
> static int z;
> };

> then you've defined (and declared) X and y, but you have only
> declared (and not defined) z. If you'd like to actually
> define z, you also need to add

> int X::z;

> Can anybody tell me the reason that the language was designed
> to be like this? It seems it would be simpler if z were
> defined in the same way as y, so presumably there's some good
> reason.

Mainly historical reasons, I suspect, but of course, if there is
an initializer (as there usually should be), you usually don't
want it in a header.

--
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

Juha Nieminen

9/29/2008 5:41:00 PM

0

James Kanze wrote:
> Mainly historical reasons, I suspect, but of course, if there is
> an initializer (as there usually should be), you usually don't
> want it in a header.

Aren't static variables always initialized to 0 (or null), even
without a specific initialization?

Juha Nieminen

9/29/2008 5:43:00 PM

0

Jeff Schwab wrote:
>> Because you only want the definition to be in one translation unit, or
>> you'll get link errors. The declarations, on the other hand, should
>> be in every translation unit that needs access to them.
>
> Btw, there's a loop-hole for class templates. Static member variables
> of class templates (not including explicit specializations) can live
> right up in the header file, along with the rest of the corresponding
> template definition.

Personally I see no reason why this should be supported for templates
and *not* for non-templates. What would be the reason for the latter?

Btw, the next standard will allow specifying initial values for member
variables in the variable definitions (so that you don't have to
initialize them explicitly in the constructor), ie:

class A
{
int i = 5, j = 10;
};

Will this extend to static member variables as well?

Andrey Tarasevich

9/29/2008 6:04:00 PM

0

Jeffrey wrote:
> My understanding is that if you write
>
> class X {
> int y;
> static int z;
> };
>
> then you've defined (and declared) X

Yes.

> and y,

No. You only _declared_ 'y' as a member of class 'X'. Non-static data
members of classes don't get [independently] _defined_ in C++ at all.
The notion is simply not applicable here.

From the less formal point of view, the purpose of defining a data
entity is to associate a storage location with it. For non-static data
members the storage is assigned when (and where) the complete object is
defined.

> but you have only declared
> (and not defined) z.

Same as with 'y' or any other data member.

> If you'd like to actually define z, you also
> need to add
>
> int X::z;

Yes. And you have to do it in one and only one translation unit.

> Can anybody tell me the reason that the language was designed to be
> like this?

When you define something that has a location in storage, the compiler
normally wants to know which translation unit this definition should be
associated with. The responsibility of choosing the translation unit is
delegated to you. This is what really hides behind the need to define it.

> It seems it would be simpler if z were defined in the same
> way as y, so presumably there's some good reason.

Firstly, you assumption that 'y' is "defined" by class definition alone
is incorrect. It isn't.

Secondly, the "definition" if 'y' (in the "storage allocation" sense)
can happen the way it happens specifically because it is a non-static
data member of the class. It can't apply to 'z'.

--
Best regards,
Andrey Tarasevich

Jeff Schwab

9/29/2008 7:35:00 PM

0

Juha Nieminen wrote:
> Jeff Schwab wrote:
>>> Because you only want the definition to be in one translation unit, or
>>> you'll get link errors. The declarations, on the other hand, should
>>> be in every translation unit that needs access to them.
>> Btw, there's a loop-hole for class templates. Static member variables
>> of class templates (not including explicit specializations) can live
>> right up in the header file, along with the rest of the corresponding
>> template definition.
>
> Personally I see no reason why this should be supported for templates
> and *not* for non-templates. What would be the reason for the latter?
>
> Btw, the next standard will allow specifying initial values for member
> variables in the variable definitions (so that you don't have to
> initialize them explicitly in the constructor), ie:
>
> class A
> {
> int i = 5, j = 10;
> };
>
> Will this extend to static member variables as well?

I don't believe so. The point of the in-class member initialization (I
would guess) is to let multiple constructors leverage common
member-initialization code, rather than all defining
similar-but-different initializer lists. The same reasoning doesn't
really apply to static members, which aren't initialized in
constructors' initializer lists at all.

AFAIK, this is the latest version of the proposal:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/...

blargg.h4g

9/29/2008 7:44:00 PM

0

In article <Pu6dnbGXo-8h333VnZ2dnUVZ_rvinZ2d@giganews.com>, Jeff Schwab
<jeff@schwabcenter.com> wrote:

> Jeffrey wrote:
> > My understanding is that if you write
> >
> > class X {
> > int y;
> > static int z;
> > };
> >
> > then you've defined (and declared) X and y, but you have only declared
> > (and not defined) z. If you'd like to actually define z, you also
> > need to add
> >
> > int X::z;
> >
> > Can anybody tell me the reason that the language was designed to be
> > like this? It seems it would be simpler if z were defined in the same
> > way as y, so presumably there's some good reason.
>
> Because you only want the definition to be in one translation unit, or
> you'll get link errors.

That's just begging the question.

James Kanze

9/30/2008 8:56:00 AM

0

On Sep 29, 7:41 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> James Kanze wrote:
> > Mainly historical reasons, I suspect, but of course, if there is
> > an initializer (as there usually should be), you usually don't
> > want it in a header.

> Aren't static variables always initialized to 0 (or null),
> even without a specific initialization?

Variables with static lifetime are "zero initialized", but that
is of limited use. You don't really want to require that all
constants be 0.

--
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