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