Static function-vars and the compiler

Discussion in 'C++' started by Marijn, Jul 28, 2003.

  1. Marijn

    Marijn Guest

    I'd like to know how compilers usually handle static variables that
    are declared inside a function (as opposed to static class-members).
    Like in:

    int counter(){
    static int c=0;
    ++c;
    return c;
    }

    I would assume the compiler changes it into something like this:

    bool counter_c_is_initialized = false;
    int counter_c;
    int counter(){
    if (!counter_c_is_initialized){
    c = 0;
    counter_c_is_initialized = true;
    }
    ++c;
    return c;
    }

    Since they do not seem to be initialized when the function is never
    called. Am i correct here? So if this is correct there will be an
    extra conditional every time the function is called.

    I've lately taken to implementing singletons with a static function
    var, something like this:

    class Singleton{
    public:
    static Singleton& get(){
    static Singleton single;
    return single;
    }
    private:
    Singleton(){}
    };

    This only works if the constructor does not take arguments, but it
    does take care of the destruction of the object when the program
    terminates. Any problems with this form of singleons? I guess i do not
    have precise control over the order in which such objects get
    destructed, so if the destructor depends on another semi-global object
    it could cause problems.

    Marijn Haverbeke
    Marijn, Jul 28, 2003
    #1
    1. Advertising

  2. "Marijn" <> wrote in message
    news:...
    > I'd like to know how compilers usually handle static variables that
    > are declared inside a function (as opposed to static class-members).
    > Like in:
    >
    > int counter(){
    > static int c=0;
    > ++c;
    > return c;
    > }
    >
    > I would assume the compiler changes it into something like this:
    >
    > bool counter_c_is_initialized = false;
    > int counter_c;
    > int counter(){
    > if (!counter_c_is_initialized){
    > c = 0;
    > counter_c_is_initialized = true;
    > }
    > ++c;
    > return c;
    > }
    >
    > Since they do not seem to be initialized when the function is never
    > called. Am i correct here?


    Some time ago I digged into the assembly output of the Borland C++
    Builder compiler. This compiler deals with static objects declared
    inside a function exactly the way you described. Unfortunately this
    solution is not multi-thread safe. I didn't check this with other
    compilers, and the standard dictates only that static objects are only
    initialized once, not how compilers should solve this problem. I.e. your
    mileage may vary.

    > So if this is correct there will be an
    > extra conditional every time the function is called.


    It is plausible that something like that will take place, though in
    theory the compiler may resort to self modifying code as well.

    > I've lately taken to implementing singletons with a static function
    > var, something like this:
    >
    > class Singleton{
    > public:
    > static Singleton& get(){
    > static Singleton single;
    > return single;
    > }
    > private:
    > Singleton(){}
    > };
    >
    > This only works if the constructor does not take arguments, but it
    > does take care of the destruction of the object when the program
    > terminates. Any problems with this form of singleons? I guess i do not
    > have precise control over the order in which such objects get
    > destructed, so if the destructor depends on another semi-global object
    > it could cause problems.


    You are correct; only the order of destruction within a translation unit
    (.cpp file) is guaranteed. The book "Modern C++ Design" from Andrei
    Alexandrescu does discusses techniques to deal with this problem.

    --
    Peter van Merkerk
    peter.van.merkerk(at)dse.nl
    Peter van Merkerk, Jul 28, 2003
    #2
    1. Advertising

  3. Marijn

    Marijn Guest

    > It is plausible that something like that will take place, though in
    > theory the compiler may resort to self modifying code as well.


    Self-modifying code? Wow, sounds weird. Do any compilers actually do
    that? That would make this static-variable-initialization much more
    efficient though. I'll try to decipher the assembly that G++ spits
    out. (My assembly reading skills are quite lousy.)

    Marijn
    Marijn, Jul 28, 2003
    #3
  4. "Marijn" <> wrote in message
    news:...
    > > It is plausible that something like that will take place, though in
    > > theory the compiler may resort to self modifying code as well.

    >
    > Self-modifying code? Wow, sounds weird. Do any compilers actually do
    > that?


    Not any that I know of. And I don't think many will since self-modifying
    code is in most cases a bad idea. I just mentioned it to make it clear that
    compilers do not have to follow the method you described. But I expect many
    compilers do the check with an additional helper variable for static objects
    with non-trivial constructors.

    Note that for primitive types like 'int' the compiler may also (and probably
    will) use initialized memory, which is set to the initial value of the
    static variable. That way no initialization check is needed when the
    function is entered.

    > That would make this static-variable-initialization much more
    > efficient though.


    static variable initialization is usually not a real performance concern.

    > I'll try to decipher the assembly that G++ spits
    > out. (My assembly reading skills are quite lousy.)


    That can be an interesting excercise. Combined with common sense it can
    provide you with valuable insights about the optimization capabilities of
    the compiler. One of the most important lessons to be learned is probably
    that many of those "clever" & dirty optimization tricks some people are
    eager to use have little or no effect on the efficiency. Some of them are
    even detrimental. An excellent example is the "integer divide by 7 trick?"
    thread of a week ago. Any halfway decent compiler will generate the optimal
    code sequence to do i/7 for a given platform. Anyone who has ever studied
    the assembly output of a contemporary compiler in recent years knows that,
    and wouldn't bother to figure how to do it with shifts and subtractions.

    Just don't get too carried away with the assembly stuff and keep in mind
    that different compilers use different solutions.

    --
    Peter van Merkerk
    peter.van.merkerk(at)dse.nl
    Peter van Merkerk, Jul 28, 2003
    #4
  5. Marijn

    Jack Klein Guest

    On 28 Jul 2003 02:24:13 -0700, (Marijn) wrote in
    comp.lang.c++:

    > I'd like to know how compilers usually handle static variables that
    > are declared inside a function (as opposed to static class-members).
    > Like in:
    >
    > int counter(){
    > static int c=0;
    > ++c;
    > return c;
    > }
    >
    > I would assume the compiler changes it into something like this:
    >
    > bool counter_c_is_initialized = false;
    > int counter_c;
    > int counter(){
    > if (!counter_c_is_initialized){
    > c = 0;
    > counter_c_is_initialized = true;
    > }
    > ++c;
    > return c;
    > }


    I would certainly hope not, at least not on "regular" desk top
    platforms. Generally the initial values for static POD data is in the
    executable image file, and it written into the proper place in memory
    by the OS program loader at the same time as it writes the executable
    binary image into a different part of memory.

    > Since they do not seem to be initialized when the function is never
    > called. Am i correct here? So if this is correct there will be an
    > extra conditional every time the function is called.


    Since there is no possible way in a conforming C++ program to find out
    the value of that static object without calling the function, it makes
    no difference whether it is initialized or not. But why do you think
    it is not?

    > I've lately taken to implementing singletons with a static function
    > var, something like this:
    >
    > class Singleton{
    > public:
    > static Singleton& get(){
    > static Singleton single;
    > return single;
    > }
    > private:
    > Singleton(){}
    > };
    >
    > This only works if the constructor does not take arguments, but it
    > does take care of the destruction of the object when the program
    > terminates. Any problems with this form of singleons? I guess i do not
    > have precise control over the order in which such objects get
    > destructed, so if the destructor depends on another semi-global object
    > it could cause problems.
    >
    > Marijn Haverbeke


    When you are talking about non-POD objects with constructors, there is
    no requirement nor guarantee that they be initialized at load-time.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
    Jack Klein, Jul 29, 2003
    #5
  6. Marijn

    Marijn Guest

    Jack Klein <> wrote in message news:<>...
    > > Since they do not seem to be initialized when the function is never
    > > called. Am i correct here? So if this is correct there will be an
    > > extra conditional every time the function is called.

    >
    > Since there is no possible way in a conforming C++ program to find out
    > the value of that static object without calling the function, it makes
    > no difference whether it is initialized or not. But why do you think
    > it is not?


    Actually, the variable might be a user-defined class, whose
    constructor has side effects. I have a logfile class singleton
    initialized as a function static as i described in my first post, and
    when it initializes it opens a file and writes something to it. When
    my program does not log anything, the logfile is not created, so that
    would prove the variable is only initialized when the function is
    actually called. Other compilers might do this differently though, i'd
    have to check.

    Marijn
    Marijn, Jul 29, 2003
    #6
    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. Jon

    app vars and cache vars

    Jon, Dec 14, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    384
  2. Jorgen Bodde

    function in a function accessing vars

    Jorgen Bodde, Jun 6, 2007, in forum: Python
    Replies:
    3
    Views:
    276
    Dustan
    Jun 6, 2007
  3. RishiD
    Replies:
    5
    Views:
    282
    Joe Greer
    Aug 7, 2008
  4. Linuxguy123
    Replies:
    7
    Views:
    670
    Paddy O'Loughlin
    Feb 20, 2009
  5. caccolangrifata
    Replies:
    18
    Views:
    385
    Chris Torek
    Jul 22, 2011
Loading...

Share This Page