简体   繁体   中英

Static variables within functions in C++ - allocated even if function doesn't run?

I've been reading up on C++ on the Internet, and here's one thing that I haven't been quite able to find an answer to.

I know that static variables used within functions are akin to globals, and that subsequent invocations of that function will have the static variable retain its value between calls.

However, if the function is never called, does the static variable get allocated?

Thanks

If the function is never called, it is likely that your linker will deadstrip both the function and the static variable, preventing it from entering .rodata , .data , or .bss segments (or your executable file format's equivalents).

However, there are various reasons why a linker might not deadstrip (flags telling it not to, an inability to determine what depends on the symbol, etc).

It's worth checking your linker map file (sometimes just a text file!), or using objdump , nm , or dumpbin utilities on the final executable to see if the symbol or related symbols (such as static initializer code) survived.

The C++ Standard, section 6.7 says:

The zero-initialization (8.5) of all local objects with static storage duration (3.7.1) is performed before any other initialization takes place. A local object of POD type (3.9) with static storage duration initialized with constant-expressions is initialized before its block is first entered. An implementation is permitted to per- form early initialization of other local objects with static storage duration under the same conditions that an implementation is permitted to statically initialize an object with static storage duration in namespace scope (3.6.2). Otherwise such an object is initialized the first time control passes through its declaration; such an object is considered initialized upon the completion of its initialization.

Which indicates that local static objects are normally initialised the first time the control flow encounters them. However, they may well be allocated before this - the standard is somewhat reticent on what static storage actually is, except with reference to static object lifetimes.

Every object in C++ has two nested time-periods associated with it: storage duration and lifetime . Storage duration is the period for which the raw memory occupied by the object is allocated. Lifetime is the period between construction and destruction of an actual object in that memory. (For objects of POD-types construction-destruction either doesn't matter or not applicable, so their lifetime matches their storage duration).

When someone says "allocated" they usually refer to storage duration . The language doesn't actually specify exactly when the object's storage duration begins. It is sufficient to require that shall begin at some point before the object's lifetime begins.

For this reason, in general case a static object defined inside a function might never begin its lifetime and, theoretically, it's storage duration does not have to begin either. So, in theory, in might not even get "allocated".

In practice though, all objects with static storage duration ("globals", local statics, etc.) are normally treated equally: they are assigned a specific amount of storage early, at the program's startup.


As an additional note, if a local object with static storage duration requires a non-trivial initialization, this initialization is carried out when the control passes over the definition for the very first time. So in this example

void foo() {
  static int *p = new int[100];
}

the dynamic array will never be allocated if the function is never called. And it will be allocated only once if the function is called. This doesn't look like what you are asking about, but I mention this just in case.

Im sure that thats going to be up to the implementation. What MSVC does is - static objects are allocated in the automatic data segment of the EXE or DLL. However, the constructor is only executed the first time the function containing the static is executed.

Yes, actual allocation is compiler dependent, although I think that every compiler just reserves the space in the .static segment of the executable (or the equivalent in its executable file format).
The initialization, however takes place only the firs time that the execution flow encounters the static object, and that is required by the standard.
Beware that initialization of global static objects works in a different way, though. You can get very good answers to almost every question at the C++ FAQ lite site. I am also fond of Scott Meyers's "Effective C++".

Depends. If you mean, never called, as in, the function is literally never invoked, then your compiler will probably not allocate it, or even put in the function code. If, however, you made it dependent on, say, user input, and that user input just happened to never come up, then it will probably be pre-allocated. However, you're treading in a minefield here, and it's best just to assume that it is always created by the time control enters the function(s) that refer to it.

Static variables defined on classes (members) or functions are not allocated dynamically on stack during function call, like non static ones. They are allocated in another area of generated code reserved for global and static data. So, if you call the function or not, instantiate classes that contain static members or not, a space to their data will be reserved on program data area anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM