Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. static member initialization order fiasco

static member initialization order fiasco

Scheduled Pinned Locked Moved C / C++ / MFC
c++htmlcomhelp
19 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Tnarol
    wrote on last edited by
    #1

    Hi, I think I experienced the issue described here with one of my classes : http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15 I realized that my static member ConfigManager::ConfigFile isn't initialized when I first call a static member function ConfigManager::GetConfigString using it. Could you have a look at my code below and suggest something to avoid this. I'm not really happy with the solution from the faq because it uses "new" to create an object instance that I can't "delete" because my class is static (no destructor). Thanks ! ConfigManager.h #pragma once #define DEFAULT_PROFILE CString("C:\\default.ini") #define DEFAULT_INT -1 #define DEFAULT_STRING CString(""); class ConfigManager { public: static CString GetConfigFile(); static void SetConfigFile(CString& p); static void SetConfig(CString section, CString key, CString value); static CString GetConfigString(CString section, CString key, CString def = DEFAULT_STRING); static int GetConfigInt(CString section, CString key, int def = DEFAULT_INT); private: static CString ConfigFile; }; ConfigManager.cpp #include "StdAfx.h" #include "ConfigManager.h" CString ConfigManager::ConfigFile = DEFAULT_PROFILE; void ConfigManager::SetConfig(CString section, CString key, CString value) { WritePrivateProfileString(section, key, value, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigString(CString section, CString key, CString def) { CString result(_T(" "),512); GetPrivateProfileString(section, key, def, result.GetBuffer(), 512, ConfigManager::ConfigFile); result.ReleaseBuffer(); return result; } int ConfigManager::GetConfigInt(CString section, CString key, int def) { return GetPrivateProfileInt(section, key, def, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigFile() { return ConfigManager::ConfigFile; } void ConfigManager::SetConfigFile(CString& p) { ConfigManager::ConfigFile = p; }

    S C W R 4 Replies Last reply
    0
    • T Tnarol

      Hi, I think I experienced the issue described here with one of my classes : http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15 I realized that my static member ConfigManager::ConfigFile isn't initialized when I first call a static member function ConfigManager::GetConfigString using it. Could you have a look at my code below and suggest something to avoid this. I'm not really happy with the solution from the faq because it uses "new" to create an object instance that I can't "delete" because my class is static (no destructor). Thanks ! ConfigManager.h #pragma once #define DEFAULT_PROFILE CString("C:\\default.ini") #define DEFAULT_INT -1 #define DEFAULT_STRING CString(""); class ConfigManager { public: static CString GetConfigFile(); static void SetConfigFile(CString& p); static void SetConfig(CString section, CString key, CString value); static CString GetConfigString(CString section, CString key, CString def = DEFAULT_STRING); static int GetConfigInt(CString section, CString key, int def = DEFAULT_INT); private: static CString ConfigFile; }; ConfigManager.cpp #include "StdAfx.h" #include "ConfigManager.h" CString ConfigManager::ConfigFile = DEFAULT_PROFILE; void ConfigManager::SetConfig(CString section, CString key, CString value) { WritePrivateProfileString(section, key, value, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigString(CString section, CString key, CString def) { CString result(_T(" "),512); GetPrivateProfileString(section, key, def, result.GetBuffer(), 512, ConfigManager::ConfigFile); result.ReleaseBuffer(); return result; } int ConfigManager::GetConfigInt(CString section, CString key, int def) { return GetPrivateProfileInt(section, key, def, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigFile() { return ConfigManager::ConfigFile; } void ConfigManager::SetConfigFile(CString& p) { ConfigManager::ConfigFile = p; }

      S Offline
      S Offline
      Steve S
      wrote on last edited by
      #2

      Do you get the same behaviour if you use CString ConfigManager::ConfigFile(DEFAULT_PROFILE); instead? Steve S Developer for hire

      T 1 Reply Last reply
      0
      • S Steve S

        Do you get the same behaviour if you use CString ConfigManager::ConfigFile(DEFAULT_PROFILE); instead? Steve S Developer for hire

        T Offline
        T Offline
        Tnarol
        wrote on last edited by
        #3

        Steve S wrote:

        CString ConfigManager::ConfigFile(DEFAULT_PROFILE);

        Just tried this, there no change. ConfigManager::ConfigFile is not initialized upon first call... then later upon second call it is.

        S 1 Reply Last reply
        0
        • T Tnarol

          Hi, I think I experienced the issue described here with one of my classes : http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15 I realized that my static member ConfigManager::ConfigFile isn't initialized when I first call a static member function ConfigManager::GetConfigString using it. Could you have a look at my code below and suggest something to avoid this. I'm not really happy with the solution from the faq because it uses "new" to create an object instance that I can't "delete" because my class is static (no destructor). Thanks ! ConfigManager.h #pragma once #define DEFAULT_PROFILE CString("C:\\default.ini") #define DEFAULT_INT -1 #define DEFAULT_STRING CString(""); class ConfigManager { public: static CString GetConfigFile(); static void SetConfigFile(CString& p); static void SetConfig(CString section, CString key, CString value); static CString GetConfigString(CString section, CString key, CString def = DEFAULT_STRING); static int GetConfigInt(CString section, CString key, int def = DEFAULT_INT); private: static CString ConfigFile; }; ConfigManager.cpp #include "StdAfx.h" #include "ConfigManager.h" CString ConfigManager::ConfigFile = DEFAULT_PROFILE; void ConfigManager::SetConfig(CString section, CString key, CString value) { WritePrivateProfileString(section, key, value, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigString(CString section, CString key, CString def) { CString result(_T(" "),512); GetPrivateProfileString(section, key, def, result.GetBuffer(), 512, ConfigManager::ConfigFile); result.ReleaseBuffer(); return result; } int ConfigManager::GetConfigInt(CString section, CString key, int def) { return GetPrivateProfileInt(section, key, def, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigFile() { return ConfigManager::ConfigFile; } void ConfigManager::SetConfigFile(CString& p) { ConfigManager::ConfigFile = p; }

          C Offline
          C Offline
          Cedric Moonen
          wrote on last edited by
          #4

          I don't have an answer to your problem but may I ask why you are using static methods only ? Maybe a singleton pattern is more suited to your needs ? (You'll have only one instance of the class). I don't really see the advantage of using only static members.


          Cédric Moonen Software developer
          Charting control

          T T 2 Replies Last reply
          0
          • C Cedric Moonen

            I don't have an answer to your problem but may I ask why you are using static methods only ? Maybe a singleton pattern is more suited to your needs ? (You'll have only one instance of the class). I don't really see the advantage of using only static members.


            Cédric Moonen Software developer
            Charting control

            T Offline
            T Offline
            toxcct
            wrote on last edited by
            #5

            Cedric Moonen wrote:

            I don't really see the advantage of using only static members

            logical grouping... in the .NET framework for instance, you have the Math class which provides only static members/functions, like square root, cosine, logarithm, etc...


            TOXCCT >>> GEII power

            [VisualCalc 3.0  updated ][Flags Beginner's Guide  new! ]

            C 1 Reply Last reply
            0
            • T toxcct

              Cedric Moonen wrote:

              I don't really see the advantage of using only static members

              logical grouping... in the .NET framework for instance, you have the Math class which provides only static members/functions, like square root, cosine, logarithm, etc...


              TOXCCT >>> GEII power

              [VisualCalc 3.0  updated ][Flags Beginner's Guide  new! ]

              C Offline
              C Offline
              Cedric Moonen
              wrote on last edited by
              #6

              toxcct wrote:

              logical grouping...

              Why not use namespace for that ?


              Cédric Moonen Software developer
              Charting control

              T 1 Reply Last reply
              0
              • C Cedric Moonen

                toxcct wrote:

                logical grouping...

                Why not use namespace for that ?


                Cédric Moonen Software developer
                Charting control

                T Offline
                T Offline
                toxcct
                wrote on last edited by
                #7

                in C++ yes... but in general OOP concepts, i'm not sure every languages know what a namespace is, unless classes scopes.


                TOXCCT >>> GEII power

                [VisualCalc 3.0  updated ][Flags Beginner's Guide  new! ]

                C 1 Reply Last reply
                0
                • T toxcct

                  in C++ yes... but in general OOP concepts, i'm not sure every languages know what a namespace is, unless classes scopes.


                  TOXCCT >>> GEII power

                  [VisualCalc 3.0  updated ][Flags Beginner's Guide  new! ]

                  C Offline
                  C Offline
                  Cedric Moonen
                  wrote on last edited by
                  #8

                  toxcct wrote:

                  in C++ yes

                  But we are on a C++ board right ;) ?


                  Cédric Moonen Software developer
                  Charting control

                  T 1 Reply Last reply
                  0
                  • C Cedric Moonen

                    toxcct wrote:

                    in C++ yes

                    But we are on a C++ board right ;) ?


                    Cédric Moonen Software developer
                    Charting control

                    T Offline
                    T Offline
                    toxcct
                    wrote on last edited by
                    #9

                    Cedric Moonen wrote:

                    But we are on a C++ board right

                    oops, you're right, i thought a moment that we were in the lounge... :doh::laugh:


                    TOXCCT >>> GEII power

                    [VisualCalc 3.0  updated ][Flags Beginner's Guide  new! ]

                    1 Reply Last reply
                    0
                    • T Tnarol

                      Hi, I think I experienced the issue described here with one of my classes : http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15 I realized that my static member ConfigManager::ConfigFile isn't initialized when I first call a static member function ConfigManager::GetConfigString using it. Could you have a look at my code below and suggest something to avoid this. I'm not really happy with the solution from the faq because it uses "new" to create an object instance that I can't "delete" because my class is static (no destructor). Thanks ! ConfigManager.h #pragma once #define DEFAULT_PROFILE CString("C:\\default.ini") #define DEFAULT_INT -1 #define DEFAULT_STRING CString(""); class ConfigManager { public: static CString GetConfigFile(); static void SetConfigFile(CString& p); static void SetConfig(CString section, CString key, CString value); static CString GetConfigString(CString section, CString key, CString def = DEFAULT_STRING); static int GetConfigInt(CString section, CString key, int def = DEFAULT_INT); private: static CString ConfigFile; }; ConfigManager.cpp #include "StdAfx.h" #include "ConfigManager.h" CString ConfigManager::ConfigFile = DEFAULT_PROFILE; void ConfigManager::SetConfig(CString section, CString key, CString value) { WritePrivateProfileString(section, key, value, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigString(CString section, CString key, CString def) { CString result(_T(" "),512); GetPrivateProfileString(section, key, def, result.GetBuffer(), 512, ConfigManager::ConfigFile); result.ReleaseBuffer(); return result; } int ConfigManager::GetConfigInt(CString section, CString key, int def) { return GetPrivateProfileInt(section, key, def, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigFile() { return ConfigManager::ConfigFile; } void ConfigManager::SetConfigFile(CString& p) { ConfigManager::ConfigFile = p; }

                      W Offline
                      W Offline
                      Weiye Chen
                      wrote on last edited by
                      #10

                      If your ConfigFile value isn't ever going to be changed, then you can do this

                      class ConfigManager
                      {
                        .
                        .
                        .
                      private:
                        static const CString ConfigFile = DEFAULT_PROFILE;
                      };

                      T 1 Reply Last reply
                      0
                      • T Tnarol

                        Steve S wrote:

                        CString ConfigManager::ConfigFile(DEFAULT_PROFILE);

                        Just tried this, there no change. ConfigManager::ConfigFile is not initialized upon first call... then later upon second call it is.

                        S Offline
                        S Offline
                        Steve S
                        wrote on last edited by
                        #11

                        Hmm. Is your call to the appropriate ConfigManager member from another static object? Steve S Developer for hire

                        1 Reply Last reply
                        0
                        • W Weiye Chen

                          If your ConfigFile value isn't ever going to be changed, then you can do this

                          class ConfigManager
                          {
                            .
                            .
                            .
                          private:
                            static const CString ConfigFile = DEFAULT_PROFILE;
                          };

                          T Offline
                          T Offline
                          toxcct
                          wrote on last edited by
                          #12

                          Weiye Chen wrote:

                          private: static const CString ConfigFile = DEFAULT_PROFILE;

                          this is not allowed in C++ (you are showing a C# solution) he must initialize its static member outise of the class


                          TOXCCT >>> GEII power

                          [VisualCalc 3.0  updated ][Flags Beginner's Guide  new! ]

                          T 1 Reply Last reply
                          0
                          • C Cedric Moonen

                            I don't have an answer to your problem but may I ask why you are using static methods only ? Maybe a singleton pattern is more suited to your needs ? (You'll have only one instance of the class). I don't really see the advantage of using only static members.


                            Cédric Moonen Software developer
                            Charting control

                            T Offline
                            T Offline
                            Tnarol
                            wrote on last edited by
                            #13

                            Cedric Moonen wrote:

                            I don't really see the advantage of using only static members.

                            Well every method of my class is standalone, it doesn't need any prerequisite to deliver a result. For me the point in having a class instance is to expect a behaviour depending on the past life of the instance. Here I don't think I need to create any (even a single) instance of the class. Eventually I'll try your idea because it is more likely to work but I think it is simplier and nicer to have ConfigMananger::GetConfigString(....) rather than ConfigManager::GetInstance()->GetConfigString(...)

                            C 1 Reply Last reply
                            0
                            • T toxcct

                              Weiye Chen wrote:

                              private: static const CString ConfigFile = DEFAULT_PROFILE;

                              this is not allowed in C++ (you are showing a C# solution) he must initialize its static member outise of the class


                              TOXCCT >>> GEII power

                              [VisualCalc 3.0  updated ][Flags Beginner's Guide  new! ]

                              T Offline
                              T Offline
                              Tnarol
                              wrote on last edited by
                              #14

                              toxcct wrote:

                              this is not allowed in C++ (you are showing a C# solution) he must initialize its static member outise of the class

                              Right, Moreover I'd like to be able to change the ConfigFile.

                              1 Reply Last reply
                              0
                              • T Tnarol

                                Hi, I think I experienced the issue described here with one of my classes : http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15 I realized that my static member ConfigManager::ConfigFile isn't initialized when I first call a static member function ConfigManager::GetConfigString using it. Could you have a look at my code below and suggest something to avoid this. I'm not really happy with the solution from the faq because it uses "new" to create an object instance that I can't "delete" because my class is static (no destructor). Thanks ! ConfigManager.h #pragma once #define DEFAULT_PROFILE CString("C:\\default.ini") #define DEFAULT_INT -1 #define DEFAULT_STRING CString(""); class ConfigManager { public: static CString GetConfigFile(); static void SetConfigFile(CString& p); static void SetConfig(CString section, CString key, CString value); static CString GetConfigString(CString section, CString key, CString def = DEFAULT_STRING); static int GetConfigInt(CString section, CString key, int def = DEFAULT_INT); private: static CString ConfigFile; }; ConfigManager.cpp #include "StdAfx.h" #include "ConfigManager.h" CString ConfigManager::ConfigFile = DEFAULT_PROFILE; void ConfigManager::SetConfig(CString section, CString key, CString value) { WritePrivateProfileString(section, key, value, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigString(CString section, CString key, CString def) { CString result(_T(" "),512); GetPrivateProfileString(section, key, def, result.GetBuffer(), 512, ConfigManager::ConfigFile); result.ReleaseBuffer(); return result; } int ConfigManager::GetConfigInt(CString section, CString key, int def) { return GetPrivateProfileInt(section, key, def, ConfigManager::ConfigFile); } CString ConfigManager::GetConfigFile() { return ConfigManager::ConfigFile; } void ConfigManager::SetConfigFile(CString& p) { ConfigManager::ConfigFile = p; }

                                R Offline
                                R Offline
                                Ryan Binns
                                wrote on last edited by
                                #15

                                You could put the constant in an anonymous namespace at the top of your implementation file, rather than in the class. You could also have GetConfigFile() set the file name if it hasn't been set, and always call it, rather than use the filename directly - that way it would always be initialised before it was used Cedric is right though. Since your class contains state, it is better implemented as a singleton, rather than a bunch of static methods and a static data member.

                                Ryan

                                "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                                T 1 Reply Last reply
                                0
                                • T Tnarol

                                  Cedric Moonen wrote:

                                  I don't really see the advantage of using only static members.

                                  Well every method of my class is standalone, it doesn't need any prerequisite to deliver a result. For me the point in having a class instance is to expect a behaviour depending on the past life of the instance. Here I don't think I need to create any (even a single) instance of the class. Eventually I'll try your idea because it is more likely to work but I think it is simplier and nicer to have ConfigMananger::GetConfigString(....) rather than ConfigManager::GetInstance()->GetConfigString(...)

                                  C Offline
                                  C Offline
                                  Cedric Moonen
                                  wrote on last edited by
                                  #16

                                  Yes, but... Why use a class then ? :) Ok, I know that you don't want to use global functions maybe but it's still clearer to declare an instance of your class first and then use the functions. Don't you think ? Otherwise, this doesn't make a lot of sense.


                                  Cédric Moonen Software developer
                                  Charting control

                                  T 1 Reply Last reply
                                  0
                                  • C Cedric Moonen

                                    Yes, but... Why use a class then ? :) Ok, I know that you don't want to use global functions maybe but it's still clearer to declare an instance of your class first and then use the functions. Don't you think ? Otherwise, this doesn't make a lot of sense.


                                    Cédric Moonen Software developer
                                    Charting control

                                    T Offline
                                    T Offline
                                    Tnarol
                                    wrote on last edited by
                                    #17

                                    Cedric Moonen wrote:

                                    Yes, but... Why use a class then ?

                                    Just to gather things that deal with the same subject...

                                    1 Reply Last reply
                                    0
                                    • R Ryan Binns

                                      You could put the constant in an anonymous namespace at the top of your implementation file, rather than in the class. You could also have GetConfigFile() set the file name if it hasn't been set, and always call it, rather than use the filename directly - that way it would always be initialised before it was used Cedric is right though. Since your class contains state, it is better implemented as a singleton, rather than a bunch of static methods and a static data member.

                                      Ryan

                                      "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                                      T Offline
                                      T Offline
                                      Tnarol
                                      wrote on last edited by
                                      #18

                                      Ryan Binns wrote:

                                      You could also have GetConfigFile() set the file name if it hasn't been set

                                      Yes I had this idea already... but did not succeed at first... I had a look again after seeing your message and it seems the following code works : CString ConfigManager::GetConfigFile() { static bool bInit = false; if (!bInit) { ConfigManager::ConfigFile = DEFAULT_FILE; bInit = true; } return ConfigManager::ConfigFile; } Thanks

                                      R 1 Reply Last reply
                                      0
                                      • T Tnarol

                                        Ryan Binns wrote:

                                        You could also have GetConfigFile() set the file name if it hasn't been set

                                        Yes I had this idea already... but did not succeed at first... I had a look again after seeing your message and it seems the following code works : CString ConfigManager::GetConfigFile() { static bool bInit = false; if (!bInit) { ConfigManager::ConfigFile = DEFAULT_FILE; bInit = true; } return ConfigManager::ConfigFile; } Thanks

                                        R Offline
                                        R Offline
                                        Ryan Binns
                                        wrote on last edited by
                                        #19

                                        Yep, that will do it. I would recommend either putting the variable in an anonymous namespace or making your class a singleton though. It's not much of a hack.

                                        Ryan

                                        "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                                        1 Reply Last reply
                                        0
                                        Reply
                                        • Reply as topic
                                        Log in to reply
                                        • Oldest to Newest
                                        • Newest to Oldest
                                        • Most Votes


                                        • Login

                                        • Don't have an account? Register

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • World
                                        • Users
                                        • Groups