static/nonstatic data member declaration/definition

Discussion in 'C++' started by Jeffrey, Sep 29, 2008.

  1. Jeffrey

    Jeffrey Guest

    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.
     
    Jeffrey, Sep 29, 2008
    #1
    1. Advertising

  2. Jeffrey

    Rolf Magnus Guest

    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.
     
    Rolf Magnus, Sep 29, 2008
    #2
    1. Advertising

  3. Jeffrey

    James Kanze Guest

    On Sep 29, 4:40 am, 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.


    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:
    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
     
    James Kanze, Sep 29, 2008
    #3
  4. 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, Sep 29, 2008
    #4
  5. 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?
     
    Juha Nieminen, Sep 29, 2008
    #5
  6. 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
     
    Andrey Tarasevich, Sep 29, 2008
    #6
  7. Jeffrey

    James Kanze Guest

    On Sep 29, 7:41 pm, Juha Nieminen <> 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:
    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
     
    James Kanze, Sep 30, 2008
    #7
  8. Jeffrey

    James Kanze Guest

    On Sep 29, 8:04 pm, Andrey Tarasevich <>
    wrote:
    > 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'.


    According to the standard, this is a definition.

    > Non-static data members of classes don't get [independently]
    > _defined_ in C++ at all. The notion is simply not applicable
    > here.


    It is according to the standard. It may not be the most
    intuitive use of language, but it works on the whole: a
    declaration which is not a definition requires a definition
    somewhere, which is not the case here.

    > From the less formal point of view, the purpose of defining a
    > data entity is to associate a storage location with it.


    Which holds here. The compiler allocates storage for y in X.

    [...]
    > > 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.


    What really hides behind it is history. The necessary
    mechanisms are needed in order to handle the case for templates.
    They weren't present in the past, however.

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


    It is according to the standard.

    --
    James Kanze (GABI Software) email:
    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
     
    James Kanze, Sep 30, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pedro López
    Replies:
    0
    Views:
    433
    Pedro López
    Oct 13, 2003
  2. Replies:
    3
    Views:
    534
  3. The|Godfather
    Replies:
    7
    Views:
    3,970
    Miles Bader
    Oct 24, 2006
  4. fl
    Replies:
    12
    Views:
    836
    Salt_Peter
    Dec 31, 2007
  5. Computerjunkie
    Replies:
    0
    Views:
    980
    Computerjunkie
    Apr 6, 2012
Loading...

Share This Page