[comp.lang.c++] Static member definition vs. declaration?

noren@dinl.uucp (Charles Noren) (04/17/91)

We have a debate in our group.  When you declare a static
member, such as:

   class X {static int myVar;};

Do you need to make a definition elsewhere,

   int X::myVar;

I claim you do (and of course you want to initialize it
at the same time).  Others in my group say you don't and
offer proof that our 2.0 and 2.1 Cfront compilers do fine
without the "int X::myVar" statement.  We all are aware
of the holy writ (ARM) on page 179 and 405, but we vary
on our interpretation of it.  I claim our compilers permit
an anachronism, the others think not.

I now humbly come and submit myself to the Wisdom of the
Network.  What is the answer?  ...and perhaps, if this is
possible, could the answer include why it is the way it is.

Much Thanks,

-- 
Chuck Noren
NET:     dinl!noren@ncar.ucar.edu
US-MAIL: Martin Marietta I&CS, MS XL8058, P.O. Box 1260,
         Denver, CO 80201-1260
Phone:   (303) 977-1646

kelley@mpd.tandem.com (Michael Kelley) (04/18/91)

In article <1848@dinl.mmc.UUCP>, noren@dinl.uucp (Charles Noren) writes:
> We have a debate in our group.  When you declare a static
> member, such as:
> 
>    class X {static int myVar;};
> 
> Do you need to make a definition elsewhere,
> 
>    int X::myVar;
> 
> I claim you do (and of course you want to initialize it
> at the same time).  Others in my group say you don't and
> offer proof that our 2.0 and 2.1 Cfront compilers do fine
> without the "int X::myVar" statement.  We all are aware
> of the holy writ (ARM) on page 179 and 405, but we vary
> on our interpretation of it.  I claim our compilers permit
> an anachronism, the others think not.
> 

Static members of fundamental types, or of a class with no constructor,
needn't be defined by the programmer.  Cfront 2.0 simply lays down a
definition for these critters, and lets the linker resolve them all
to the same address.  It can't be done for objects with constructors,
however, because it would be incorrect for all modules which "see" 
the static member to reinitialize it. I think not *having* to make
the definition in some cases has been rightly deemed an anachronism,
if for no other reason than you, I, and others having to ask
"do we or don't we?".  It's also prone to cause problems because
the default definitions will be zeroed out, which may not make any
sense.  I imagine that in future (2.2+?) releases, you will get link
errors on all static members not explicitly defined, and not just
those with constructors like you do now.

Mike Kelley
Tandem Computers, Austin, TX
kelley@mpd.tandem.com
(512) 244-8830 / Fax (512) 244-8247

noren@dinl.uucp (Charles Noren) (04/19/91)

Thanks to all who have responded to my question.  I've
tried thanking personally to all who responded but my
mail often bounces.

The answer to the question of a static member declaration,
e.g.,

   class X {static int myVar;};

is that somewhere the static member must be defined, such as,

   int X::myVar;

The reason my compiler permitted no definition was that my
linker was probably smart to infer a definition when one was
not explicitly found.  Also many have pointed out that C++
compilers imperfectly implement the C++ "standard".

Thanks again.


-- 
Chuck Noren
NET:     dinl!noren@ncar.ucar.edu
US-MAIL: Martin Marietta I&CS, MS XL8058, P.O. Box 1260,
         Denver, CO 80201-1260
Phone:   (303) 977-1646

rmartin@clear.com (Bob Martin) (04/19/91)

In article <1848@dinl.mmc.UUCP> noren@dinl.UUCP (Charles Noren) writes:
>We have a debate in our group.  When you declare a static
>member, such as:
>
>   class X {static int myVar;};
>
>Do you need to make a definition elsewhere,
>
>   int X::myVar;
>

Although the source will compile without the definition, I have been
unable to get it to link without it.  It seems that (at least with
Sun's 2.0 compiler) the declaration in the class is _not_ a
definition, and that a true definition is required.

-- 
+-Robert C. Martin-----+:RRR:::CCC:M:::::M:| Nobody is responsible for |
| rmartin@clear.com    |:R::R:C::::M:M:M:M:| my words but me.  I want  |
| uunet!clrcom!rmartin |:RRR::C::::M::M::M:| all the credit, and all   |
+----------------------+:R::R::CCC:M:::::M:| the blame.  So there.     |

comeau@ditka.Chicago.COM (Greg Comeau) (04/22/91)

In article <186@devnull.mpd.tandem.com> kelley@mpd.tandem.com (Michael Kelley) writes:
>In article <1848@dinl.mmc.UUCP>, noren@dinl.uucp (Charles Noren) writes:
>>    class X {static int myVar;};
>> Do you need to make a definition elsewhere,
>>    int X::myVar;
>> I claim you do (and of course you want to initialize it

You *do*.  A static member only serves as a declaration, and not a
definition hence a definition still needs to be provided.

>Static members of fundamental types, or of a class with no constructor,
>needn't be defined by the programmer.  Cfront 2.0 simply lays down a

Check out the ARM, p179: "The declaration of a static data member in its
class declaration is *not* a definition.  A definition is required elsewhere".
This characteristic is definitely in the 2.1 language spec and I believe
was also in 2.0's (although I'm not sure anymore).

>definition for these critters, and lets the linker resolve them all
>to the same address.  It can't be done for objects with constructors,

It's not quite that it lets the linker but that that's how the UNIX
linker, like most linkers, unfortunately work (in the so-called
relaxed definition mode of ANSI C).  In any event, implementation are
currently in a state of transition on this issue.  Nevertheless, it is
an anacronism in all cases.

>sense.  I imagine that in future (2.2+?) releases, you will get link
>errors on all static members not explicitly defined, and not just
>those with constructors like you do now.

Again, 2.1 already has this.  It's up to the "compiler system" to enforce it.

- Greg
-- 
	 Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418
                            Producers of Comeau C++
          Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421
                     Voice:718-945-0009 / Fax:718-441-2310

avraamid@camelback.crd.ge.com (David Avraamides) (04/24/91)

In article <37226@ditka.Chicago.COM> comeau@ditka.Chicago.COM (Greg Comeau) writes:
# In article <186@devnull.mpd.tandem.com> kelley@mpd.tandem.com (Michael Kelley) writes:
# >In article <1848@dinl.mmc.UUCP>, noren@dinl.uucp (Charles Noren) writes:
# >>    class X {static int myVar;};
# >> Do you need to make a definition elsewhere,
# >>    int X::myVar;
# >> I claim you do (and of course you want to initialize it
# 
# You *do*.  A static member only serves as a declaration, and not a
# definition hence a definition still needs to be provided.
# 

What if its not public? Does this make sense?

I use a static numInstances variable in my root class and ++ it in
all constructors and -- it in all destructors. I don't want it to
be publicly visible. What if I don't want it to start at 0? (My
compiler doesn't make me initialize it.)
--
Dave Avraamides
avraamides@crd.ge.com
All opinions are my own...

steve@taumet.com (Stephen Clamage) (04/26/91)

avraamid@camelback.crd.ge.com (David Avraamides) writes:

># You *do*.  A static member only serves as a declaration, and not a
># definition hence a definition still needs to be provided.

>What if its not public? Does this make sense?

Of course.  Private member functions still need to be defined
somewhere, and so do private static data members, for example.
The fact that they are defined does not make them more available
to client functions.

>I use a static numInstances variable in my root class and ++ it in
>all constructors and -- it in all destructors. I don't want it to
>be publicly visible. What if I don't want it to start at 0? (My
>compiler doesn't make me initialize it.)

Root.h:
=======
class Root { ... private: static int numInstances; ... };

Root.c:
=======
int Root::numInstances = <initial value>;

Only members and friends of class Root can get at numInstances, since it
is private; no user can see the initializer, since it is hidden in
file Root.c.  In C++, this is the best you can do with any private
data or function.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

cadsi@ccad.uiowa.edu (CADSI) (05/01/91)

From article <1991Apr19.133728.5300@clear.com>, by rmartin@clear.com (Bob Martin):
> In article <1848@dinl.mmc.UUCP> noren@dinl.UUCP (Charles Noren) writes:
>>We have a debate in our group.  When you declare a static
>>member, such as:
>>
>>   class X {static int myVar;};
>>
>>Do you need to make a definition elsewhere,
>>
>>   int X::myVar;
>>
> 
> Although the source will compile without the definition, I have been
> unable to get it to link without it.  It seems that (at least with
> Sun's 2.0 compiler) the declaration in the class is _not_ a
> definition, and that a true definition is required.
> 

Correct, in C++ 2.0, static class members MUST be allocated outside the
class structure.

|----------------------------------------------------------------------------|
|Tom Hite					|  The views expressed by me |
|Manager, Product development			|  are mine, not necessarily |
|CADSI (Computer Aided Design Software Inc.	|  the views of CADSI.       |
|----------------------------------------------------------------------------|

jimad@microsoft.UUCP (Jim ADCOCK) (05/08/91)

|We have a debate in our group.  When you declare a static
|member, such as:
|
|   class X {static int myVar;};
|
|Do you need to make a definition elsewhere,
|
|   int X::myVar;
|

In C++ static members are only allowed for global classes.  The mention of such
inside of the class is only a declaration, the actual definition must
occur at file scope.

Some C++ compilers allow declaration without such explicit definition.
This is a *compiler* anachronism as listed in section 18.3 of ARM, not part
of the C++ *language* as defined today.

randolph@tuna.ssd.kodak.com (Gary L. Randolph) (05/08/91)

In article <72218@microsoft.UUCP> jimad@microsoft.UUCP (Jim ADCOCK) writes:
>|We have a debate in our group.  When you declare a static
>|member, such as:
>|
>|   class X {static int myVar;};
>|
>|Do you need to make a definition elsewhere,
>|
>|   int X::myVar;
>|
>
>In C++ static members are only allowed for global classes.  The mention of such
>inside of the class is only a declaration, the actual definition must
>occur at file scope.
>
>Some C++ compilers allow declaration without such explicit definition.
>This is a *compiler* anachronism as listed in section 18.3 of ARM, not part
>of the C++ *language* as defined today.

What Jim says is certainly true. I have an additional comment and a suggestion
that you obviously may ignore.

comment:

One point that may be news to at least the novice C++er is that static members
have external linkage.  This is not what C programmers are used to.  In fact
many programmers believe that static MEANS private and permanent. Usually it 
does.  This is an exception.

suggestion:

As Jim implies, you should never rely on a compiler allowing you to forego the
definition. 

Gary