On Local and Global Static Variables in C++

C local and global static variables

You messed up all. Static local variable is a place to hide data from other functions but retain data for future calls of that function.

Static global variables have

  • static storage duration (Retain data for future call)
  • internal linkage (variable is restricted to single file) and
  • file scope (Only in the current file the variable can be referenced)

Static local variables have

  • static storage duration
  • no linkage
  • block scope

Difference between static global variable and non-static global variable in C

There are basically four cases:

  • declared outside of function, without static
  • declared outside of function, with static
  • declared inside of function, without static
  • declared inside of function, with static

Let's cover these in turn.

Declared outside of function, without static

This is a conventional global symbol. You can access it from any source file (although in that other source file, you typically need an extern declaration).

Declared outside of function, with static

This is the "static" global you were asking about. You can access it only within the source file where it is defined. It's "private" to that source file, but you can access it from any function in that source file (well, actually, any function in that source file that occurs below its declaration). Like any global variable, it maintains its value for the life of the program.

Declared inside of function, without static

This is a conventional local variable. You can access it only within that function. Each time the function is called (including recursively), you get a new instance of the variable. If you don't initialize it, it starts out containing an unpredictable value. It does not maintain its value between calls.

Declared inside of function, with static

This is a static local variable. You can access it only within that function. There is exactly one copy of it, shared between all calls to the function (including recursive calls). If you don't initialize it, it starts out zero. It maintains its value between calls.

In three of these cases, if you don't provide an explicit initializer, a variable is guaranteed to be initialized to 0. But in the case of true local variables, if you don't provide an explicit initializer,
it starts out containing an unpredictable value, which you can't depend on.

Formally, there are two concepts here, visibility and lifetime. True global variables are visible anywhere in the program. Static global variables are visible only in their source file. Local variables are visible only in their function. All global variables, and all static variables, have static duration — they last for as long as the program does. (Also these are the ones that are guaranteed to be initialized to 0.) True local variables have "automatic" duration — they come and go as the containing function is called and returns.

Closely related to duration is the question of where variables will actually be stored. Static-duration variables are typically stored in the data segment. Automatic-duration variables are typically — though not necessarily — stored on the stack.

C++, What is difference between static local variable(method) vs global(file) variable?

Other answers have told you the differences between a local static object (local to a function) and a non-local static object (static objects declared global or in a namespace); however, you should also understand the importance of using one over the other.

The information I use here comes from Effective C++ Third Edition by Scott Myers (a recommended and excellent read)

A static object is one that exists from the time it's constructed until the end of the program.

As others have mentioned, a non-local static object is constructed before main whereas a local static object is constructed the first time the function is called.

But what if you had two static objects and one relied on the other. How could you be sure that one would be constructed before the other? You can't: The relative order of initialisation of non-local static objects defined in different translation units is undefined

Scott Myers definition of a translation unit (from aforementioned book):

A translation unit is the source code giving rise to a single object file. It's basically a single source file, plus all of the #include files.

So imagine you have these two non-local static objects in separate source files, you couldn't guarantee one would be constructed before the other. This is where a local static object prevails!

Consider Scott Myers' example of a FileSystem class and a Directory class, where the Directory relies on the FileSystem:

class FileSystem
{
public:
size_t numDisks() const;
};
extern FileSystem tfs;

and

class Directory
{
public:
Directory()
{
size_t disks = tfs.numDisks();
...
}
};

If Directory gets constructed before FileSystem, then you are going to be using an uninitialised class! Fortunately, you can get around this by using local static objects!

class FileSystem
{
public:
size_t numDisks() const;
};
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}

Now when Directory is constructed, even if it's constructed before FileSystem is, FileSystem is guaranteed to be constructed before it's used!

On local and global static variables in C++

The differences are:

  • The name is only accessible within the function, and has no linkage.
  • It is initialised the first time execution reaches the definition, not necessarily during the program's initialisation phases.

The second difference can be useful to avoid the static intialisation order fiasco, where global variables can be accessed before they're initialised. By replacing the global variable with a function that returns a reference to a local static variable, you can guarantee that it's initialised before anything accesses it. (However, there's still no guarantee that it won't be destroyed before anything finishes accessing it; you still need to take great care if you think you need a globally-accessible variable. See the comments for a link to help in that situation.)

How global and local with same static variable names stored in C internally memory?

#include<stdio.h>
static int a=5;
int main()
{
printf("%p\n",(void *)&a);
static int a=15;
printf("%p\n",(void *)&a);
return 0;
}

Output for the upper program is

0x564e6b67a030
0x564e6b67a034

So you can see that both are stored in different addresses. As one is a global variable and other is local.

How do you disambiguate a local static variable and a global variable that have the same name

Q1-inside f(), there is a local static varaible x defined, and there is gloabal variable also called x, isn't it a conflict to the compiler and linker?

No, the function always treats the local variable name first. The local name x in function f shadows the global name x.

Q2-when I run it, the output is 1, which means that the x in x += 1; is the local static varaible x, not the gloabal variable x.But I could have mean "increment the global variable x", how can I do it?

It's the same as your first question. You call f() which uses the local variable name x, which shadows the global name x. If you want the global x, you need to use it directly, not via function f.

How global static and local static variables in C won't clash

why the compiler is not giving error

Because those two variables have different scope, which means they are two different variable from the viewpoint of a compiler.

how the names are resolved

Compiler may give them different names.

For example

static int x;

void foo(void) {
static int x;
}

here is the symbols for both x:

$ readelf -s t108.o | grep x
Num: Value Size Type Bind Vis Ndx Name
5: 0000000000000000 4 OBJECT LOCAL DEFAULT 3 x
6: 0000000000000004 4 OBJECT LOCAL DEFAULT 3 x.1707

Static variables in global and local scope in C

It indicates the local static variable aa from the scope of func, this variable is initialized only once by the dynamic loader of the system. It is not seen from outside of the translation unit, but it is also in data segment, as this is where the initialization is made fast at the beginning.

The index 2286 is randomly generated, such that if you declare many variables named aa statically in different local scopes, to be able to distinguish each other and in the same time to keep all in data segment.



Related Topics



Leave a reply



Submit