1

Static variables exist outside of the function, in terms of their memory at least (not scope), right? But one thing that always concerned me, is what happens when I call the function a second time. For instance:

f(){
    static char buffer[256*256];
    stuff(buffer);
}

When I call this function a second time, wouldn't it technically be declaring the variable 'buffer' a second time? Or does it work differently with static variables (as opposed to normal ones) once everything is compiled?

... I sometimes wish there was a chart or something of what a c++ compiler usually turns code into (minus optimizations) so I wouldn't have to bother you fine folks with little questions like this, aha. Thank you in advance!

edit: I know it works like this, I just want to know why though. It's probably something mind numbingly simple...

trincot
  • 317,000
  • 35
  • 244
  • 286
Anne Quinn
  • 12,609
  • 8
  • 54
  • 101

5 Answers5

3

No, you static means that it is outside the scope of your function. It has the same effect as writing:

static char buffer[256*256];

f(){
    stuff(buffer);
}

Except that the buffer is only visible in the scope of your function, and the code is more readable.

(NOTE: My example doesn't apply when char is not a primitive type - in that case, it is constructed the first time it is "declared").

EboMike
  • 76,846
  • 14
  • 164
  • 167
  • Okay, I'll have to remember this scoping rule! – Anne Quinn Mar 03 '11 at 22:16
  • 1
    Btw, here's an example of how the variable - if it's a class - only gets constructed when you declare it: http://codepad.org/7LQpGnIn – EboMike Mar 03 '11 at 22:19
  • ... oh! The reason I never used classes as a static member was this exactly, not knowing how to properly initialize it. Figured I couldn't count on the constructor because I didn't know when it'd be called. Don't have to worry about that no more. Thanks for the example! – Anne Quinn Mar 03 '11 at 22:23
  • This is not correct, `static` doesn't affect the scope of a variable declared in the body of a function. A variable declared `static` is still not accessible outside of the function, it's scope is not equivalent to declaring a variable at namespace scope; it's the storage duration that is affected. – CB Bailey Mar 03 '11 at 22:48
3

Static storage duration objects in function scope.

These objects are created on first use.
Then destroyed in reverse order of creation (with other static storage duration objects).

#include <iostream>

class X
{
    public:
        X(int x): m(x)      {std::cout << "X: " << m << " created\n"; }
        ~X()                {std::cout << "X: " << m << " destroyed\n";}

    private:
        int m;
};


static X    x1(1);

int test()
{
    std::cout << "Test: Start\n";
    static  X x3(3);

    std::cout << "Test: Finished\n";
    return 5;
}


int main()
{
    std::cout << "Main: Start\n";
    X   x2(2);

    test();

    X   x4(4);
    std::cout << "Main: Finished\n";
}

Now Try it: (comments added). SSDO => Static Storage Duration object.

g++ X.cpp
./a.out
X: 1 created    // SSDO file scope.
Main: Start
X: 2 created
Test: Start
X: 3 created    // SSDO created on first use (Notice not destroyed)
Test: Finished
Test: Start     // Notice not created here.
Test: Finished
X: 4 created
Main: Finished
X: 4 destroyed
X: 2 destroyed  // Main now really finished. after destroying local variables.
X: 3 destroyed  // Destroy SSDO in reverse order of creation. (3 - 1)
X: 1 destroyed
Martin York
  • 257,169
  • 86
  • 333
  • 562
1

In this context, static means that the variable has application lifetime. It is allocated before main() the function is entered, and deallocated after main() has returned. Also, its value is preserved between function calls. Think of it as a global variable that is only visible from inside that function.

suszterpatt
  • 8,187
  • 39
  • 60
  • Okay, so the compiler makes it so all the memory is allocated before everything else starts running. That's what I wanted to know! I thought it created the memory the first time the function was called instead. – Anne Quinn Mar 03 '11 at 22:10
  • 2
    No quite correct. It is allocated on first use. Then all static storage duration objects are destroyed in reverse order of creation when main exits. Now the compiler may pre-allocate space for a static buffer like this as an optimization but technically it does not exist until it is first used. – Martin York Mar 03 '11 at 22:17
  • @Martin: yes, I wasn't sure of that, so I went to look at [the standard](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf). However, it says (3.7.1.1): "The storage for these objects shall last for the duration of the program (3.6.2, 3.6.3)." OTOH, 3.6.2 describes "Initialization of non-local objects", and I have yet to find a section about local statics. In short, I will defer to your expertise. :) – suszterpatt Mar 03 '11 at 22:42
  • @MartinYork: Technically, as a POD variable with static storage duration it does exist for the lifetime of the program (even before the function is entered for the first time) and it will be zero-initialized. It's an academic point because there is no way to reference the variable before control passes through the declaration in the function. See the discussions here: http://stackoverflow.com/questions/4977290 . – CB Bailey Mar 03 '11 at 22:54
  • @Charles: Based on the wording of 3.7.1 (says the storage (not the variable)) I could quibble here. BUT as you say academic and in the end I could be wrong and humiliated. So I humbly concede the point :-) – Martin York Mar 04 '11 at 00:20
  • @MartinYork: Combine 3.7.1 with 3.8/1 (and the note in 3.8/2) and you have that the lifetime of objects other than those of class type with a non-trivial constructor starts when their storage is obtained. – CB Bailey Mar 04 '11 at 10:21
0

The variable exists before and after you call the function...it's static.

Steve Wellens
  • 20,506
  • 2
  • 28
  • 69
0

This example might illustrate it:

#include <iostream>
using namespace std;

void test() {
  static int i = 123;
  if (i == 123) {
    i = 321;
  }
  cout << i << endl;
}

int main(int arg, char **argv) {
  test();
  test();
  return 0;
}

The output is:

321

321

So "i" is only initialized the first time it is encountered, so to speak. But actually it's allocated at compile time for that function. Afterwards, it's just in the scope of the function test() as a variable, but it is static so changing it changes it in all future calls to test() as well.

Morten Kristensen
  • 7,412
  • 4
  • 32
  • 52
  • So even though i is assigned 123 at the very start of the function, this is never done again in that function. This is what had me confused! So I guess like another answer said, it moves this initialization to the value of 123 to before the program enters main()? edit: Actually, reading all the answers together, it seems it does this except when it's an object. Okay! That's all I needed to know! Thank you! – Anne Quinn Mar 03 '11 at 22:14
  • If you change i into a class and do some printing from the constructor/destructor you will see that it does not exist until after first use (though the compiler may have already pre-allocated space for it). – Martin York Mar 03 '11 at 22:20
  • 1
    @Clairvoire: For simple cases like this the compiler may have optimized it so that it so that it contains 123 at compile time. But technically it does not exist until the first time the function is called. The first time (and only the first time) the object will be initialized (POD like this will be assigned class objects will have their constructor called). – Martin York Mar 03 '11 at 22:22
  • @Martin: Okay, that's the major thing that confused me. But now I know exactly when they're created and destroyed. This was probably the main reason I never declared anything static until now, the ambiguity involved. (I actually thought you had to be careful and initialize the variable in it's own branch in the function or something similarly awful). Thanks for clearing all this up for me! Aha, I almost wish I could award the answer thing to comments on other answers. – Anne Quinn Mar 03 '11 at 22:29