user358186
user358186

Reputation:

Non-Static Data Duration in Static Functions

I would like to initialize a static array of abstract interfaces. I'm just wondering if a call to a static function to build the data is a valid means of initialization. What will the lifetime of the data that the pointer is pointing to in the code below look like?

typedef class FOO {
public:
    static const int** array_int;
    static const int** array_int_init();

} FOO;

const int** FOO::array_int_init()
{
    const int A = 5;
    const int B = 6;
    const int C = 7;

    const int* array_int[] = { &A, &B, &C };

    return &array_int[0];
}
const int** FOO::array_int = array_int_init();

Also what is the best way to find specifics about behaviors like this in the C++ specification? I have N3225=10-0215 but even looking at the index and the content I find I would need to read a lot with no promise of an answer.

Upvotes: 0

Views: 135

Answers (2)

6502
6502

Reputation: 114491

Your variables are locals and they will cease to exist when the function exits. If you need them to survive then declare both vars and array as static inside the function with

const int** array_int_init()
{
    static const int A = 5;
    static const int B = 6;
    static const int C = 7;

    static const int* array_int[] = { &A, &B, &C };

    return &array_int[0];
}

These static variables will last as long as the program and will be initialized the first time you call the function (note that in case of multithreading however some extra handling is needed if initialization is not as trivial as the case above).

Upvotes: 2

Tal Pressman
Tal Pressman

Reputation: 7317

Looking at your code, it seems that instead of the method actually initializing the static data member 'array_int' it creates a local array with the same name and returns that as its return value. This actually causes 2 bugs:

  1. The 'array_int' member is left uninitialized. EDIT: My mistake, didn't notice that you initialize the static member with the return value. Ignore this point.
  2. The return value of 'array_int_init()' is the address of the local array, which will not be valid once the method returns. Actually, the values in that array point themselves to other local int variables, whose addresses will also not be valid once the function returns.

But, to answer your general question, yes - it is enough to call a static class function (it doesn't even have to return anything) to initialize static class members, and they will stay initialized until the program ends.

EDIT: Based on the comments, I guess there's some confusion here so I'll try to give a better explanation.

In the original code, there is a static data member called FOO::array_int. That data member is not initialized or accessed in the code.

There is also a local variable in the function array_int_init(), whose address is returned as the function's return value. Now, since both that static variable and all the int variables whose addresses are used to populate that array are all allocated on the stack, they are no longer valid once the function returns (meaning that accessing those addresses will result in undefined behavior). The reason it seems to work in VC10 is that you are accessing the returned array right after the function returns, before any other information is allocated on the stack that overwrites the previous data. That, however, will not work in a 'real' application.

Upvotes: 1

Related Questions