Initialization of static members/constants???

Discussion in 'C++' started by Bret Pehrson, Dec 8, 2004.

  1. Bret Pehrson

    Bret Pehrson Guest

    I just stumbled across the following problem:

    //.h
    class Masses
    {
    static double mass1;
    static double mass2;
    static double mass3;
    };

    //.cpp
    double Masses::mass1 = 123.0;
    double Masses::mass2 = 456.0;
    double Masses::mass3 = mass1/mass2;


    // elsewhere (other translation unit)
    double m = Masses::mass3; // m and Masses::mass3 == 0!


    If I change mass3 initialization to a non-arithmetic literal, all works; leave
    as arithmetic operation, and the value is set to 0.

    So, my question is this: does the language mandate the initialization order of
    such constants? I thought that it was based on the declaration order in the
    class definition, but if that is the case, then mass3 should have a non-zero
    value.

    Is this a problem w/ my compiler (MSVC 2003), or a misunderstanding of the
    language on my part?

    FWIW: I also tried using static const in a namespace instead of as class
    members, same behavior.

    Thanks
    Bret Pehrson, Dec 8, 2004
    #1
    1. Advertising

  2. Bret Pehrson wrote:
    > I just stumbled across the following problem:
    >
    > //.h
    > class Masses
    > {
    > static double mass1;
    > static double mass2;
    > static double mass3;
    > };
    >
    > //.cpp
    > double Masses::mass1 = 123.0;
    > double Masses::mass2 = 456.0;
    > double Masses::mass3 = mass1/mass2;
    >
    >
    > // elsewhere (other translation unit)
    > double m = Masses::mass3; // m and Masses::mass3 == 0!
    >
    >
    > If I change mass3 initialization to a non-arithmetic literal, all works; leave
    > as arithmetic operation, and the value is set to 0.
    >
    > So, my question is this: does the language mandate the initialization order of
    > such constants?


    Only within the same translation unit.

    > I thought that it was based on the declaration order in the
    > class definition, but if that is the case, then mass3 should have a non-zero
    > value.
    >
    > Is this a problem w/ my compiler (MSVC 2003), or a misunderstanding of the
    > language on my part?


    Yes, it's a misunderstanding. Read about "static initialisation order
    fiasco" in the FAQ ( http://www.parashift.com/c -faq-lite/ )

    > FWIW: I also tried using static const in a namespace instead of as class
    > members, same behavior.


    Placing them in a namespace instead of a class shouldn't really matter.

    V
    Victor Bazarov, Dec 8, 2004
    #2
    1. Advertising

  3. Bret Pehrson

    Bret Pehrson Guest

    Victor Bazarov wrote:
    >
    > Bret Pehrson wrote:
    > > I just stumbled across the following problem:
    > >
    > > //.h
    > > class Masses
    > > {
    > > static double mass1;
    > > static double mass2;
    > > static double mass3;
    > > };
    > >
    > > //.cpp
    > > double Masses::mass1 = 123.0;
    > > double Masses::mass2 = 456.0;
    > > double Masses::mass3 = mass1/mass2;
    > >
    > >
    > > // elsewhere (other translation unit)
    > > double m = Masses::mass3; // m and Masses::mass3 == 0!
    > >
    > >
    > > If I change mass3 initialization to a non-arithmetic literal, all works; leave
    > > as arithmetic operation, and the value is set to 0.
    > >
    > > So, my question is this: does the language mandate the initialization order of
    > > such constants?

    >
    > Only within the same translation unit.
    >
    > > I thought that it was based on the declaration order in the
    > > class definition, but if that is the case, then mass3 should have a non-zero
    > > value.
    > >
    > > Is this a problem w/ my compiler (MSVC 2003), or a misunderstanding of the
    > > language on my part?

    >
    > Yes, it's a misunderstanding. Read about "static initialisation order
    > fiasco" in the FAQ ( http://www.parashift.com/c -faq-lite/ )


    Yes, but these constants are declared/initialized in the same translation
    unit. In my sample above, the .h represents 1 header, .cpp 1 source, and
    elsewhere, is just the use of those class statics in some other context other
    than the .cpp translation unit.

    According to my understanding and what I've read, the SIOF only applies to
    static initialization _across_ translation units, not within.

    I'm presuming this is a compiler bug, and have simply resorted to using
    non-arithmetic literals for constants initializers.
    Bret Pehrson, Dec 9, 2004
    #3
  4. Bret Pehrson wrote:
    > Victor Bazarov wrote:
    >
    >>Bret Pehrson wrote:
    >>
    >>>I just stumbled across the following problem:
    >>>
    >>>//.h
    >>>class Masses
    >>>{
    >>> static double mass1;
    >>> static double mass2;
    >>> static double mass3;
    >>>};
    >>>
    >>>//.cpp
    >>>double Masses::mass1 = 123.0;
    >>>double Masses::mass2 = 456.0;
    >>>double Masses::mass3 = mass1/mass2;
    >>>
    >>>
    >>>// elsewhere (other translation unit)

    ^^^^^^^^^^^^^^^^^^^^^^
    >>>double m = Masses::mass3; // m and Masses::mass3 == 0!


    > [...]
    >
    > Yes, but these constants are declared/initialized in the same translation

    ^^^^^^^^^^^^^^^
    Uh, who is crazy here, I or you?

    > unit. In my sample above, the .h represents 1 header, .cpp 1 source, and
    > elsewhere, is just the use of those class statics in some other context other
    > than the .cpp translation unit.
    >
    > According to my understanding and what I've read, the SIOF only applies to
    > static initialization _across_ translation units, not within.


    So, if the 'm' object is in a different ("other") translation unit than
    the 'Masses::mass3' object, would it make them "within" or "across"?

    > I'm presuming this is a compiler bug, and have simply resorted to using
    > non-arithmetic literals for constants initializers.


    No, it's not a compiler bug.

    V
    Victor Bazarov, Dec 9, 2004
    #4
  5. Bret Pehrson

    Bret Pehrson Guest

    Victor Bazarov wrote:
    >
    > Bret Pehrson wrote:
    > > Victor Bazarov wrote:
    > >
    > >>Bret Pehrson wrote:
    > >>
    > >>>I just stumbled across the following problem:
    > >>>
    > >>>//.h
    > >>>class Masses
    > >>>{
    > >>> static double mass1;
    > >>> static double mass2;
    > >>> static double mass3;
    > >>>};
    > >>>
    > >>>//.cpp
    > >>>double Masses::mass1 = 123.0;
    > >>>double Masses::mass2 = 456.0;
    > >>>double Masses::mass3 = mass1/mass2;
    > >>>
    > >>>
    > >>>// elsewhere (other translation unit)

    > ^^^^^^^^^^^^^^^^^^^^^^
    > >>>double m = Masses::mass3; // m and Masses::mass3 == 0!

    >
    > > [...]
    > >
    > > Yes, but these constants are declared/initialized in the same translation

    > ^^^^^^^^^^^^^^^
    > Uh, who is crazy here, I or you?


    Well, not me, but I'll admit to a poorly constructed sample -- see below.

    > > unit. In my sample above, the .h represents 1 header, .cpp 1 source, and
    > > elsewhere, is just the use of those class statics in some other context other
    > > than the .cpp translation unit.
    > >
    > > According to my understanding and what I've read, the SIOF only applies to
    > > static initialization _across_ translation units, not within.

    >
    > So, if the 'm' object is in a different ("other") translation unit than
    > the 'Masses::mass3' object, would it make them "within" or "across"?


    Ok, I see the point of confusion. m isn't another static, simply a local
    variable. A more accurate complete snippet should be:

    // assuming previous .h and .cpp snippet from op

    // elsewhere (other translation unit)
    int main()
    {
    double m = Masses::mass3; // m and Masses::mass3 == 0!
    return 0;
    }

    This is what I intended to portray in my original sample, but didn't adequately
    describe that.

    I'm presuming this is a compiler bug, and have simply resorted to using
    non-arithmetic literals for constants initializers.
    Bret Pehrson, Dec 9, 2004
    #5
    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. JFCM
    Replies:
    4
    Views:
    5,732
  2. Victor Bazarov
    Replies:
    2
    Views:
    396
    red floyd
    Aug 1, 2003
  3. DanielBradley
    Replies:
    3
    Views:
    14,924
    Dave Moore
    Jun 2, 2004
  4. BigMan
    Replies:
    7
    Views:
    476
    Axter
    Mar 1, 2005
  5. Steve Folly
    Replies:
    3
    Views:
    456
    James Kanze
    Apr 20, 2007
Loading...

Share This Page