Static class member initialization question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Michael Klatt

    Static class member initialization question

    I am working on a library which uses the GKS graphics package. I have
    a Gks object which opens the GKS subsystem in its constructor:

    // Gks.hpp

    class Gks
    {
    public :
    Gks();
    };


    --------------------

    // Gks.cpp

    #include "Gks.hpp"
    Gks::Gks()
    {
    // open GKS subsystem
    }


    I have several types of object which need the GKS subsystem to be
    opened before they can be created. I need something like a global
    static Gks object, but since this is tricky to do in a library I'm
    trying a solution that uses inheritence. All classes which need a
    static Gks object derive from GksInit:

    // GksInit.hpp
    #include "Gks.hpp"

    class GksInit
    {
    public :
    virtual ~GksInit() {}

    protected :
    GksInit();

    private :
    static const Gks ourGks;
    };

    --------------------------

    //GksInit.cpp
    #include "GksInit.hp p"

    const Gks GksInit::ourGks ; // make sure GKS gets initialized

    GksInit::GksIni t() {}


    ----------------

    // Workstation.hpp
    // GKS needs to be initialized before a Workstation can be created
    #include "GksInit.hp p"

    class Workstation : public GksInit
    {
    ...
    };


    This all seems to work as desired, but here is my problem/question.
    If I inline the GksInit constructor in the header file, the
    GksInit::ourGks static member never gets constructed. Why is this?
  • lilburne

    #2
    Re: Static class member initialization question

    Michael Klatt wrote:
    [color=blue]
    >
    > This all seems to work as desired, but here is my problem/question.
    > If I inline the GksInit constructor in the header file, the
    > GksInit::ourGks static member never gets constructed. Why is this?[/color]

    Static member variables are initialized before main is
    called. The inheritance GksInit and construction of a
    GksInit has nothing to do with it.

    Are you sure you haven't removed the

    'const Gks GksInit::ourGks ;'

    declaration from the cpp file?


    Comment

    • Andrey Tarasevich

      #3
      Re: Static class member initialization question

      lilburne wrote:[color=blue][color=green]
      >>
      >> This all seems to work as desired, but here is my problem/question.
      >> If I inline the GksInit constructor in the header file, the
      >> GksInit::ourGks static member never gets constructed. Why is this?[/color]
      >
      > Static member variables are initialized before main is
      > called. The inheritance GksInit and construction of a
      > GksInit has nothing to do with it.
      > ...[/color]

      No, dynamically initialized non-local objects are guaranteed to be
      initialized before the first use of any function defined in the same
      translation unit. This means that non-local objects, which are defined
      in the same translation unit with 'main', are guaranteed to be
      initialized before 'main' is called. But there's no such guarantee for
      non-local objects defined in other translation units.

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • lilburne

        #4
        Re: Static class member initialization question

        Andrey Tarasevich wrote:
        [color=blue]
        > lilburne wrote:
        >[color=green][color=darkred]
        >>>This all seems to work as desired, but here is my problem/question.
        >>>If I inline the GksInit constructor in the header file, the
        >>>GksInit::our Gks static member never gets constructed. Why is this?[/color]
        >>
        >>Static member variables are initialized before main is
        >>called. The inheritance GksInit and construction of a
        >>GksInit has nothing to do with it.
        >>...[/color]
        >
        >
        > No, dynamically initialized non-local objects are guaranteed to be
        > initialized before the first use of any function defined in the same
        > translation unit. This means that non-local objects, which are defined
        > in the same translation unit with 'main', are guaranteed to be
        > initialized before 'main' is called. But there's no such guarantee for
        > non-local objects defined in other translation units.
        >[/color]

        True you can't guarantee initialisation order across
        translation usits, but doesn't his GksInit::ourGks having
        static storage duration guarantee it being initialized
        before any dynamic initialization occurs?

        Comment

        • Michael Klatt

          #5
          Re: Static class member initialization question

          mdklatt@ou.edu (Michael Klatt) wrote in message news:<2cb75565. 0311111232.4917 2fdf@posting.go ogle.com>...[color=blue]
          > I am working on a library which uses the GKS graphics package. I have
          > a Gks object which opens the GKS subsystem in its constructor:
          >
          > // Gks.hpp
          >
          > class Gks
          > {
          > public :
          > Gks();
          > };
          >
          >
          > --------------------
          >
          > // Gks.cpp
          >
          > #include "Gks.hpp"
          > Gks::Gks()
          > {
          > // open GKS subsystem
          > }
          >
          >
          > I have several types of object which need the GKS subsystem to be
          > opened before they can be created. I need something like a global
          > static Gks object, but since this is tricky to do in a library I'm
          > trying a solution that uses inheritence. All classes which need a
          > static Gks object derive from GksInit:
          >
          > // GksInit.hpp
          > #include "Gks.hpp"
          >
          > class GksInit
          > {
          > public :
          > virtual ~GksInit() {}
          >
          > protected :
          > GksInit();
          >
          > private :
          > static const Gks ourGks;
          > };
          >
          > --------------------------
          >
          > //GksInit.cpp
          > #include "GksInit.hp p"
          >
          > const Gks GksInit::ourGks ; // make sure GKS gets initialized
          >
          > GksInit::GksIni t() {}
          >[/color]

          I just want to reiterate my question. The code I have posted here
          seems to work as I expect. However, if I inline the GksInit
          constructor in the header file, the constructor for static member
          ourGks never gets called. The only difference is the inlined
          constructor; the GksInit source file still contains the definition of
          ourGks.

          Why does it matter if the GksInit() is inlined or defined in the
          source file?

          Comment

          • Victor Bazarov

            #6
            Re: Static class member initialization question

            "Michael Klatt" <mdklatt@ou.edu > wrote...[color=blue]
            > mdklatt@ou.edu (Michael Klatt) wrote in message[/color]
            news:<2cb75565. 0311111232.4917 2fdf@posting.go ogle.com>...[color=blue][color=green]
            > > I am working on a library which uses the GKS graphics package. I have
            > > a Gks object which opens the GKS subsystem in its constructor:
            > >
            > > // Gks.hpp
            > >
            > > class Gks
            > > {
            > > public :
            > > Gks();
            > > };
            > >
            > >
            > > --------------------
            > >
            > > // Gks.cpp
            > >
            > > #include "Gks.hpp"
            > > Gks::Gks()
            > > {
            > > // open GKS subsystem
            > > }
            > >
            > >
            > > I have several types of object which need the GKS subsystem to be
            > > opened before they can be created. I need something like a global
            > > static Gks object, but since this is tricky to do in a library I'm
            > > trying a solution that uses inheritence. All classes which need a
            > > static Gks object derive from GksInit:
            > >
            > > // GksInit.hpp
            > > #include "Gks.hpp"
            > >
            > > class GksInit
            > > {
            > > public :
            > > virtual ~GksInit() {}
            > >
            > > protected :
            > > GksInit();
            > >
            > > private :
            > > static const Gks ourGks;
            > > };
            > >
            > > --------------------------
            > >
            > > //GksInit.cpp
            > > #include "GksInit.hp p"
            > >
            > > const Gks GksInit::ourGks ; // make sure GKS gets initialized
            > >
            > > GksInit::GksIni t() {}
            > >[/color]
            >
            > I just want to reiterate my question. The code I have posted here
            > seems to work as I expect. However, if I inline the GksInit
            > constructor in the header file, the constructor for static member
            > ourGks never gets called. The only difference is the inlined
            > constructor; the GksInit source file still contains the definition of
            > ourGks.
            >
            > Why does it matter if the GksInit() is inlined or defined in the
            > source file?[/color]

            Sounds like a bug in the compiler. Perhaps it discards any consts
            if they are not used anywhere else in the system. See if using
            a different compiler would fix the problem.

            Victor



            Comment

            • Jesper Madsen

              #7
              Re: Static class member initialization question

              I think you should make a function instead, it usually helps, not all
              compilers like statics floating around.

              Just do a:
              Gtk& GtkInstance(){
              static Gtk ourGtk;
              return ourGtk;
              }

              Jesper


              Comment

              Working...