Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Static Member variable and static member function resides in ????
Forum Updated to NodeBB v4.3 + New Features

Static Member variable and static member function resides in ????

Scheduled Pinned Locked Moved Unsolved C++ Gurus
22 Posts 7 Posters 4.9k Views 6 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.
  • V Offline
    V Offline
    Vinoth Rajendran4
    wrote on last edited by Vinoth Rajendran4
    #1

    Hello All,
    I would like to know where static member function and static member variable for a class resides in memory layout?

    Any help is appreciated.

    1 Reply Last reply
    0
    • Chris KawaC Online
      Chris KawaC Online
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      In terms of memory placement static member is basically like a variable in global scope. Same with a member function - it's like a free function outside of classes. The class scope is just syntax and visibility management, sorta like a namespace.

      1 Reply Last reply
      8
      • Kent-DorfmanK Offline
        Kent-DorfmanK Offline
        Kent-Dorfman
        wrote on last edited by
        #3

        If you were working for me I'd have to ask "why do you care?" Are you attempting to leverage some behaviour outside of the language specification? If so, consider carefully because therein lies introduction of bugs.

        fcarneyF 1 Reply Last reply
        -1
        • Kent-DorfmanK Kent-Dorfman

          If you were working for me I'd have to ask "why do you care?" Are you attempting to leverage some behaviour outside of the language specification? If so, consider carefully because therein lies introduction of bugs.

          fcarneyF Offline
          fcarneyF Offline
          fcarney
          wrote on last edited by
          #4

          @Kent-Dorfman Knowing memory layout can be REALLY important. The lack of that knowledge can introduce bugs. Like the static initialization order problems. It should also be noted that static/global vars are initialized by the OS before main executes. While this init may not occur on an embedded system with no OS. So it can affect portability of code.

          C++ is a perfectly valid school of magic.

          JonBJ 1 Reply Last reply
          2
          • Kent-DorfmanK Offline
            Kent-DorfmanK Offline
            Kent-Dorfman
            wrote on last edited by Kent-Dorfman
            #5

            In c++ a design that is sensitive to static order initialization is itself suspect, and shouldn't pass a reasonable code review. It's not the OS that initializes anything in a c++ elf or a.out image. it is typically a small linked in object called crt0.o and since the order of global/static initialization in c++ is undefined, it should never be relied upon, even if a particular platform is observed to behave a certain way.

            The well defined and verifiable work-around is the "constuct on first use idiom". None of which requires internal knowledge of program memory layout in c++.

            These kinds of discussions remind me of things like editing vtables in c++. There should never be a reason to do so, and in fact, the language specification doesn't even require their existence.

            Chris KawaC 1 Reply Last reply
            0
            • Kent-DorfmanK Kent-Dorfman

              In c++ a design that is sensitive to static order initialization is itself suspect, and shouldn't pass a reasonable code review. It's not the OS that initializes anything in a c++ elf or a.out image. it is typically a small linked in object called crt0.o and since the order of global/static initialization in c++ is undefined, it should never be relied upon, even if a particular platform is observed to behave a certain way.

              The well defined and verifiable work-around is the "constuct on first use idiom". None of which requires internal knowledge of program memory layout in c++.

              These kinds of discussions remind me of things like editing vtables in c++. There should never be a reason to do so, and in fact, the language specification doesn't even require their existence.

              Chris KawaC Online
              Chris KawaC Online
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by Chris Kawa
              #6

              @Kent-Dorfman said:

              These kinds of discussions remind me of things like editing vtables in c++. There should never be a reason to do so

              I disagree. It's not like "if it's not in C++ standard it doesn't exist". The hardware is hardware and doesn't care for high level languages. OSes rarely have C++ API only, so to leverage some fine grained features of these you sometimes need to rely on hardware/OS guarantees, not those of C++ standard.
              Sure, I'm not saying you should rely on static initialization order because there's just no guarantee at all, C++ or otherwise, but that's not what OP was asking and I don't see anything wrong in wanting to know how stuff works. I see that as a positive. Curiosity in programming is a good trait in my view, even if you don't necessarily immediately apply everything you're curious about. I think saying "you shouldn't be asking that" is a trait of bad teacher, not bad student.

              As an example - I wouldn't automatically take a question about undefined behavior as a sign that someone wants to exploit it, but rather someone trying to avoid it. Same here - asking about statics can lead to better usage of them and avoiding some of their traps.

              1 Reply Last reply
              4
              • fcarneyF fcarney

                @Kent-Dorfman Knowing memory layout can be REALLY important. The lack of that knowledge can introduce bugs. Like the static initialization order problems. It should also be noted that static/global vars are initialized by the OS before main executes. While this init may not occur on an embedded system with no OS. So it can affect portability of code.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #7

                @fcarney said in Static Member variable and static member function resides in ????:

                @Kent-Dorfman Knowing memory layout can be REALLY important. The lack of that knowledge can introduce bugs. Like the static initialization order problems.

                Since this question is still going on: How does knowing anything about memory layout address anything about the static initialization order problem you linked to?

                fcarneyF 1 Reply Last reply
                0
                • JonBJ JonB

                  @fcarney said in Static Member variable and static member function resides in ????:

                  @Kent-Dorfman Knowing memory layout can be REALLY important. The lack of that knowledge can introduce bugs. Like the static initialization order problems.

                  Since this question is still going on: How does knowing anything about memory layout address anything about the static initialization order problem you linked to?

                  fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #8

                  @JonB I kinda lumped it into knowing when and where things are happening. That problem in particular may not be all that relevant. I found it interesting because I found out that the OS does initialize the global memory for the app at startup ("and is zeroed out by the OS when loading the program"). This zero init does not happen on systems without an OS so may provide challenges for portability of code. I found this out when researching why I was having init problems of static/global variables that accessed the same data structure from different compilation units. This lead to a series of investigations to find out if I really did need to init some variables or not. There was a constructor that would overwrite things when it wasn't really needed. That code is legacy and needs to be reworked, but unfortunately it is production code at the moment. So yeah, not directly related, but definitely in a similar realm of knowledge in my mind. To me, at times, it has been important to have some kind of idea of memory layout when coding. Of course this is more important when doing things system wise like firmware development or microcontrollers. Desktop apps, not so much, unless memory is highly constrained for some reason. Then it might be important.

                  C++ is a perfectly valid school of magic.

                  jsulmJ 1 Reply Last reply
                  0
                  • fcarneyF fcarney

                    @JonB I kinda lumped it into knowing when and where things are happening. That problem in particular may not be all that relevant. I found it interesting because I found out that the OS does initialize the global memory for the app at startup ("and is zeroed out by the OS when loading the program"). This zero init does not happen on systems without an OS so may provide challenges for portability of code. I found this out when researching why I was having init problems of static/global variables that accessed the same data structure from different compilation units. This lead to a series of investigations to find out if I really did need to init some variables or not. There was a constructor that would overwrite things when it wasn't really needed. That code is legacy and needs to be reworked, but unfortunately it is production code at the moment. So yeah, not directly related, but definitely in a similar realm of knowledge in my mind. To me, at times, it has been important to have some kind of idea of memory layout when coding. Of course this is more important when doing things system wise like firmware development or microcontrollers. Desktop apps, not so much, unless memory is highly constrained for some reason. Then it might be important.

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @fcarney Just a note: you should always initialize all your variables and not trust OS/framework/whatever to do it for you :-)

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    Chris KawaC 1 Reply Last reply
                    0
                    • jsulmJ jsulm

                      @fcarney Just a note: you should always initialize all your variables and not trust OS/framework/whatever to do it for you :-)

                      Chris KawaC Online
                      Chris KawaC Online
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @jsulm I'd say you should usually initialize your variables. There are a lot of C style APIs out there that, for example, take a reference to a data structure and fill it out. Initializing the members beforehand is just wasteful and compiler can't always optimize redundant writes like that, especially on function boundaries. I've seen a case with code like

                      Foo array_of_foos[COUNT];
                      ...
                      Initialize(array_of_foos);
                      

                      where someone innocently enough did a static analysis pass and the tool suggested

                      Foo array_of_foos[COUNT] {};
                      

                      This started to show up badly in profiles. Generally I would avoid words like "always" and "never" in C++. "Most of the time" or "rarely" seem to fit a lot better with reality.

                      1 Reply Last reply
                      4
                      • JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #11

                        I'm a touch confused about one thing which is being said. (Yes, I could go look it up somewhere, but I prefer to ask here.)

                        Earlier @fcarney said in Static Member variable and static member function resides in ????:

                        It should also be noted that static/global vars are initialized by the OS before main executes. While this init may not occur on an embedded system with no OS. So it can affect portability of code.

                        int fred[100];
                        
                        void func()
                        {
                            static char jim[100];
                        }
                        

                        In my day both fred & jim were guaranteed initialized to 0s (zeroes), and AFAIR that was specified in the C language. Are you saying that an OS implementation does not have to do that, so it's not a feature of the language?

                        1 Reply Last reply
                        0
                        • fcarneyF Offline
                          fcarneyF Offline
                          fcarney
                          wrote on last edited by
                          #12

                          I am going by what cppreference says. It says the OS initializes some things. I have no idea if the OS "has" to or not. My guess it is supposed to. On an embedded system, without an OS, then there is no OS to init this memory.

                          C++ is a perfectly valid school of magic.

                          1 Reply Last reply
                          0
                          • Chris KawaC Online
                            Chris KawaC Online
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            @fcarney said:

                            I am going by what cppreference says. It says the OS initializes some things. I have no idea if the OS "has" to or not. My guess it is supposed to.

                            C++ standard says those are initialized. It does not say an OS should or shouldn't do that. It has no notion of an OS. How this initialization is done is implementation defined and a conforming toolchain will do whatever is required to achieve that effect on given platform. In some cases it may be a compile time initialization stored in the executable image, for some the OS loader may take care of that at load time and for other cases (like no OS) the compiler might generate explicit code run before main() to initialize those variables. The point is that C++ standard does not define how a given effect is to be achieved, only that it is. This is intentional, as it does not impose artificial requirements on platforms and is left for toolchain implementers to do whatever is the best option for their platform.

                            fcarneyF 1 Reply Last reply
                            4
                            • kshegunovK Offline
                              kshegunovK Offline
                              kshegunov
                              Moderators
                              wrote on last edited by kshegunov
                              #14

                              These discussions are so cool! :)

                              Edit:
                              @Chris-Kawa said in Static Member variable and static member function resides in ????:

                              How this initialization is done is implementation defined

                              With major note that the standard dictates trivial initializations happen before non-trivial ones. And this is a behaviour one can rely on.

                              Read and abide by the Qt Code of Conduct

                              1 Reply Last reply
                              5
                              • Chris KawaC Chris Kawa

                                @fcarney said:

                                I am going by what cppreference says. It says the OS initializes some things. I have no idea if the OS "has" to or not. My guess it is supposed to.

                                C++ standard says those are initialized. It does not say an OS should or shouldn't do that. It has no notion of an OS. How this initialization is done is implementation defined and a conforming toolchain will do whatever is required to achieve that effect on given platform. In some cases it may be a compile time initialization stored in the executable image, for some the OS loader may take care of that at load time and for other cases (like no OS) the compiler might generate explicit code run before main() to initialize those variables. The point is that C++ standard does not define how a given effect is to be achieved, only that it is. This is intentional, as it does not impose artificial requirements on platforms and is left for toolchain implementers to do whatever is the best option for their platform.

                                fcarneyF Offline
                                fcarneyF Offline
                                fcarney
                                wrote on last edited by
                                #15

                                @Chris-Kawa said in Static Member variable and static member function resides in ????:

                                left for toolchain implementers to do whatever is the best option for their platform

                                So I did test this on an embedded platform. It was an Arduino IDE based platform (Teensy 4 in this case). It does indeed init arrays declared in the global/static region of the code. For testing I created an array of structs. Looping through I was able to confirm that everything was zeroed out. Thanks for the clarification.

                                C++ is a perfectly valid school of magic.

                                1 Reply Last reply
                                1
                                • Kent-DorfmanK Offline
                                  Kent-DorfmanK Offline
                                  Kent-Dorfman
                                  wrote on last edited by
                                  #16

                                  @fcarney said in Static Member variable and static member function resides in ????:

                                  For testing I created an array of structs. Looping through I was able to confirm that everything was zeroed out. Thanks for the clarification.

                                  That's not a valid test. initailize with a unique bit pattern. Power off, then restart the board and verify the bit patterns after reinitialization. Also read the standard regarding object/variable initialization. The rules are here:
                                  https://en.cppreference.com/w/cpp/language/default_initialization

                                  What is not defined is the order of static initialization. Thats why it is important to initialize static members as part of the main() startup: "construct on first use".

                                  Chris KawaC 1 Reply Last reply
                                  0
                                  • Kent-DorfmanK Kent-Dorfman

                                    @fcarney said in Static Member variable and static member function resides in ????:

                                    For testing I created an array of structs. Looping through I was able to confirm that everything was zeroed out. Thanks for the clarification.

                                    That's not a valid test. initailize with a unique bit pattern. Power off, then restart the board and verify the bit patterns after reinitialization. Also read the standard regarding object/variable initialization. The rules are here:
                                    https://en.cppreference.com/w/cpp/language/default_initialization

                                    What is not defined is the order of static initialization. Thats why it is important to initialize static members as part of the main() startup: "construct on first use".

                                    Chris KawaC Online
                                    Chris KawaC Online
                                    Chris Kawa
                                    Lifetime Qt Champion
                                    wrote on last edited by Chris Kawa
                                    #17

                                    @Kent-Dorfman said in Static Member variable and static member function resides in ????:

                                    Thats why it is important to initialize static members as part of the main() startup: "construct on first use".

                                    No, that's not how it works. Global static variables are initialized before main(). They might have side effects which need to be visible before the variable itself is used. Heck, there might even not be any main() in your program. For example MFC framework has just a static global variable that runs event loop from its constructor. There usually is no main() in such app and yet it still runs.

                                    JonBJ 1 Reply Last reply
                                    3
                                    • Chris KawaC Chris Kawa

                                      @Kent-Dorfman said in Static Member variable and static member function resides in ????:

                                      Thats why it is important to initialize static members as part of the main() startup: "construct on first use".

                                      No, that's not how it works. Global static variables are initialized before main(). They might have side effects which need to be visible before the variable itself is used. Heck, there might even not be any main() in your program. For example MFC framework has just a static global variable that runs event loop from its constructor. There usually is no main() in such app and yet it still runs.

                                      JonBJ Offline
                                      JonBJ Offline
                                      JonB
                                      wrote on last edited by JonB
                                      #18

                                      Further to @Chris-Kawa's (correct) observation above about "Global static variables".

                                      Turning to non-global scope static variables. A few months we had an interesting discussion in this forum about when these get initialized, but I don't have the reference to the thread. We were talking either about statics declared in a function, or in a class, or both, I don't recall.

                                      We found these are indeed only initialized on "first use" of the function/class/whatever. We looked at the code generated to accomplish this. It turns out that the compiler generated a "hidden guard variable/memory location" for these. Effectively like a boolean initialized to 0/false to say "not yet called for initialization". On being called/created, the code tests this variable and does the initialization once at this instant if the boolean is still false. Then it sets the boolean to true, so that initialization will not occur again.

                                      This allows e.g. a static initialization somewhere to reference, say, another class/object which itself is not ready to be called at start up time; it will not evaluate the reference until the calling code is actually first executed, thereby allowing the referenced object to have been initialized itself.

                                      I at least found the "hidden guard" code implementation interesting :)

                                      1 Reply Last reply
                                      2
                                      • Chris KawaC Online
                                        Chris KawaC Online
                                        Chris Kawa
                                        Lifetime Qt Champion
                                        wrote on last edited by Chris Kawa
                                        #19

                                        Yeah, function local statics are scoped, so they behave a little different. This case of static init was further complicated in C++11. Before that C++ standard had no notion of threads, so initialization of static variable in a function called simultaneously from different threads was undefined - it could be initialized once, twice, at all, partially or crash your app entirely. In C++11 this is guaranteed to be initialized exactly once. It's not specified from which thread that init occurs, only that the observed behavior is that on first use in any thread the variable is fully initialized. This got nicknamed as "magic statics". It's important to note that because of the synchronization needed function statics initialization in C++11 became kinda costly operation, so it's something to keep in mind. This also lead to a new storage specifier - thread_local.

                                        kshegunovK 1 Reply Last reply
                                        2
                                        • Chris KawaC Chris Kawa

                                          Yeah, function local statics are scoped, so they behave a little different. This case of static init was further complicated in C++11. Before that C++ standard had no notion of threads, so initialization of static variable in a function called simultaneously from different threads was undefined - it could be initialized once, twice, at all, partially or crash your app entirely. In C++11 this is guaranteed to be initialized exactly once. It's not specified from which thread that init occurs, only that the observed behavior is that on first use in any thread the variable is fully initialized. This got nicknamed as "magic statics". It's important to note that because of the synchronization needed function statics initialization in C++11 became kinda costly operation, so it's something to keep in mind. This also lead to a new storage specifier - thread_local.

                                          kshegunovK Offline
                                          kshegunovK Offline
                                          kshegunov
                                          Moderators
                                          wrote on last edited by
                                          #20

                                          @Chris-Kawa said in Static Member variable and static member function resides in ????:

                                          It's important to note that because of the synchronization needed function statics initialization in C++11 became kinda costly operation, so it's something to keep in mind.

                                          Sort of, but on the bright side function static initialization happens on first use only (threads notwithstanding), so if you never call the method that inits it, it is never initialized (which is not true for class's statics that are the same as globals).

                                          Read and abide by the Qt Code of Conduct

                                          1 Reply Last reply
                                          3

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved