Reading over someone else's code, I saw something syntactically similar to this:
int main(void) {
static int attr[] = {FOO, BAR, BAZ, 0};
/* ... */
}
Is this an error or is there some reason to declare a variable in main static? As I understand it static prevents linkage and maintains value between invocations. Because here it's inside a function it only does the latter, but main is only invoked once so I don't see the point. Does this modify some compilation behavior (e.g. preventing it from being optimized out of existence)?
Unless you're doing something very non-standard such as calling main directly, there's little point in declaring local variables static in main.
What it is useful for however is if you have some large structure used in main that would be too big for the stack. Then, declaring the variable as static means it lives in the data segment.
Being static also means that, if uninitialized, the variable will be initialized with all 0's, just like globals.
static also tells the compiler to store the data in .data section of memory where globals are typically stored. You can use this for large arrays that might overflow the stack.
Related
We know that when the control exits from function the stack space will be freed. So what happens for static variables. Will they be saved in any memory and retrieved when the function gets called ??
The wiki says:
In the C programming language, static is used with global variables
and functions to set their scope to the containing file. In local
variables, static is used to store the variable in the statically
allocated memory instead of the automatically allocated memory. While
the language does not dictate the implementation of either type of
memory, statically allocated memory is typically reserved in data
segment of the program at compile time, while the automatically
allocated memory is normally implemented as a transient call stack.
and
Static local variables: variables declared as static inside a function
are statically allocated while having the same scope as automatic
local variables. Hence whatever values the function puts into its
static local variables during one call will still be present when the
function is called again.
Yes, static variables persist between function calls. They reside in data section of the program, like global variables.
You can (and probably should) read more about general memory layout of C applications here.
Adding some more information on top of previously given answers -
The memory for static objects is allocated at compile/link time. Their address is fixed by the linker based on the linker control file.
The linker file defines the physical memory layout (Flash/SRAM) and placement of the different program regions.
The static region is actually subdivided into two further sections, one for initial value, and the other for changes done in run time.
And finally, remember that if you will not specify otherwise, the value will be set to 0 during compilation.
You made an incorrect assumption that static variables are placed on the stack* when the function that uses them is running, so they need to be saved and retrieved.
This is not how C does it: static variables are allocated in an entirely different memory segment outside of stack, so they do not get freed when the function ends the scope of its automatic variables.
Typically, static data segment is created and initialized once upon entering the program. After that the segment stays allocated for as long as your program is running. All your global variables, along with the static variables from all functions, are placed in this segment by the compiler. That is why entering or leaving functions has no effect on these variables.
* The official name for "stack" is "automatic storage area".
Consider this example:
static int foo;
void f(void)
{
static int bar;
}
The only difference between foo and bar is that foo has file scope whereas bar has function scope. Both variables exist during the whole lifetime of the program.
In C ,what is the use of static storage class when an external variable can serve its purpose at the same cost ie. both occupy storage space in the data segment of the executable.
I have much better scope with external variable.If i want the scope of external variable to be specific file i do not declare this variable else where.i see a lot of flexibility with a global variable that static local variable
And we can refer to local static variable outside the function if we have the address of the variable.Memory for local static variable will be in Data segment not in the stack frame of the function.So unique feature does static storage class bring to the table.
I just want to know whether static has any subtle purpose that i m not aware of.
You write that a global variable has a “better” scope. This is incorrect. It has a bigger scope. Bigger is not better.
Bigger may be necessary, if you need an identifier to be visible in more places, but this is often not the case. But a bigger scope means more exposure to errors. Global variables muddle the semantics of routines by making it harder to see what program state they use and change, and it increases the probability of errors caused by failing to declare a local identifier and of other errors.
In particular, an identifier with external linkage will collide with identifiers in other libraries. Consider what happens when you are writing a physics application, have an external identifier named acceleration, and link with a physics library that also has an external identifier named acceleration. The program will fail. Because of this, external identifiers are usually bad design.
A significant limit on our ability to develop and maintain complex software is human error. Much of programming language semantics limits the language to prevent errors. With a raw computer, you can add two pointers, trash your stack pointer, accidentally load the bytes of a float into an integer register, and so on. Good programming languages make these errors difficult to do by mistake.
Global variables were a larger source of errors before scoping rules helped control them. Good programmers limit the scopes of their identifiers.
A global variable is well, global, it can be accessed from anywhere.
A static local variable has local scope. It is static, so it's lifetime runs across the lifetime of the application however it can only be accessed from the local scope (whether that scope is a function, a block, or a file)
The basic difference is on scope of variable.
1) global variable is global for entire project. lets say your project has 10 different files then all 10 files can access the global variable(see how to use extern).
2) static variable/function can be used by function/file within which it is defined. It cannot be used by any other file in your project.
yet, you can modify the static variable(defined in func1()) in func2() by passing reference of the variable. please look into below example,
void func2(int *i)
{
(*i)++;
}
void func1()
{
static int i;
i=1;
printf("%d\n", i);
func2(&i);
printf("%d\n", i);
}
int main()
{
func1();
return 0;
}
As you see above, func1() has static int i which cannot be directly manipulated by func2(), but if you pass reference of the variable you can still manipulate the variable like ordinary variable.
hope it helps...
Difference between local and global first and foremost is the scope: you can access local variables only from within the block they're defined in, while global variables can be accessed from anywhere. Consequently, you can only have one variable with a given name in global scope, but you can have multiple local static variables in different functions.
As with static global variables versus extern variables: yes, static global variables are local to the translation unit (i.e. the .c source file they're defined in).
So the main concern here is the notion of scope, and the storage comes naturally from there.
The reason you should use a local static variable is scope, and therefore avoiding some bug prone situations since using a local static variable you'll not be able to refer to it outside the function it was defined in.
Here's a short program which demonstrates the difference:
#include <stdio.h>
static int a=20;
void local()
{
printf("%d,addr:%d \n", a, (void*)&a);
a = 100;
}
int main()
{
{
static int a = 10;
printf("%d,addr:%d \n", a, (void*)&a);
local();
}
printf("%d addr:%d \n", a, (void*)&a);
}
Output:
10,addr:134518604 -- local static inside the braces
20,addr:134518600 -- this is referring the global static variable
100 addr:134518600 -- This is referring the global static variable which is outside of
the braces.
Here braces also matters: if no braces in the main() function then it refers local static variable only.
I have a choice to between declaring a variable static or global.
I want to use the variable in one function to maintain counter.
for example
void count()
{
static int a=0;
for(i=0;i<7;i++)
{
a++;
}
}
My other choice is to declare the variable a as global.
I will only use it in this function count().
Which way is the safest solution?
It matters only at compile and link-time. A static local variable should be stored and initialised in exactly the same way as a global one.
Declaring a local static variable only affects its visibility at the language level, making it visible only in the enclosing function, though with a global lifetime.
A global variable (or any object in general) not marked static has external linkage and the linker will consider the symbol when merging each of the object files.
A global variable marked static only has internal linkage within the current translation unit, and the linker will not see such a symbol when merging the individual translation units.
The internal static is probably better from a code-readability point of view, if you'll only ever use it inside that function.
If it was global, some other function could potentially modify it, which could be dangerous.
Either using global or static variable within a function both are not safe because then your function will no longer be re-entrant.
However if you are not concerned with function being re-entrant then you can have either based on your choice.
If the variable is only to be accessed within the function count() then it is by definition local, so I cannot see why the question arises. As a rule, always use the most restrictive scope possible for any symbol.
You should really read Jack Ganssle's article A Pox on Globals, it will be enlightening.
Always reduce scope as far as possible. If a variable doesn't need to be visible outside a function, it should not be declared outside it either. The static keyword should be used whenever possible. If you declare a variable at file scope, it should always be static to reduce the scope to the file it was declared in. This is C's way of private encapsulation.
The above is true for all systems. For embedded there is another concern: all variables declared as static or global must be initialized before the program is started. This is enforced by ISO C. So they are always set either to the value the programmer wants them initialized to. If the programmer didn't set any value they are initialized to zero (or NULL).
This means that before main is called, there must be a snippet executed in your program that sets all these static/global values. In an embedded system, the initialization values are copied from ROM (flash, eeprom etc) to RAM. A standard C compiler handles this by creating this snippet and adding it to your program.
However, in embedded systems this snippet is often unfortunate, as it leads to a delay at program startup, especially if there is lots of statics/globals. A common non-standard optimization most embedded compilers support, is to remove this snippet. The program will then no longer behave as expected by the C standard, but it will be faster. Once you have done this optimization, initialization must be done in runtime, roughly static int x; x=0; rather than static int x=0;.
To make your program portable to such non-standard embedded compilers, it is a good habit to always set your globals/statics in runtime. And no matter if you intend to port to such compilers or not, it is certainly a good habit not to rely on the default zero initialization of globals/statics. Because most rookie C programmers don't even know that this static zero initialization rule exists and they will get very confused if you don't init your variables explicitly before using them.
i dont think is there is anything special with static & normal global with embedded domain ...!!
in one way static is good that if you are going to initialize your counter as o in starting then if you just declare with static then there is no need to initialize with it 0 because every static varaible is by default initialized with 0.
Edit :
After Clifford's comment i have checked and get to know that globals are also statically allocated and initialised to zero, so that advantage does not exist..
Pass a pointer to a "standard" variable instead
void count(int *a) {
int i;
for (i = 0; i < 7; i++)
{
(*a)++;
}
}
This way you do not rely neither on global variables nor on static local variables, which makes your program better.
I would say static is better than global if you want only one function to access it in which you declared it . Plus global variables are more prone to be accidentally accessed by other functions.
If you do want to use globals since it can be accessed by other functions in the program, make sure you declare them as volatile .
volatile int a = 0;
volatile makes sure it is not optimised by compilers in the wrong way.
I have a question in allocation of memory for static variables. Please look at the following snippet.
#include<stdio.h>
#include<conio.h>
void fun();
static int a;
void main()
{
fun();
getch();
}
void fun()
{
static int b;
}
Can someone please explain me when memory will be allocated for static int b in function fun (before main is executed or when the function is located). I knew that memory for static will be allocated only once, but I want to knew when memory will be allocated for it. Please explain.
I am using 64 bit processor, turbo c compiler, windows 7 operating system.
Memory for static variables is allocated when your program is loaded. Static variables in a function are initialized before the function is called for the first time.
Memory for statics is normally allocated basically as the program loads/just before it starts to execute.
Memory for static variables (both a and b in the example question) is allocated at compile time. You can verify this by examining your map file. Be aware that, depending on the detail provided in the map file, you may not see the variable name of the static variable, rather simply that the corresponding amount of memory has been allocated. They are initialized when the program is loaded along with the global variables...not the first time the function is called.
Statics live in the same place as globals. The space for them is set at compile time and allocated at load time.
When static is used inside a function block, the keyword static changes the storage class of the variable or function, which means static int b; is saying that b is a static variable rather than an automatic one.
When talking about storage class, static one is initialized in static memory before the program runs, and is there all the time when the program runs, while automatic one is initialized in run-time stack or heap when reaches certain block and is destroyed when the program goes out of the block.
When static is used outside as in the static int a; shows, this is rather another case. It changes the linkage of the variable to be internal while the default value is external. And it has nothing to do with the storage class of the variable or function.
With static, a is internal, which means it is only accessible to those within this file. Without static, a is set to be external by default, which means it is accessible to those within and out of the file where a is defined.
There is no allocation for b in this case. It is an int, and is added to the stack when the application is loaded.
What are the differences between static and external variables? What are the advantages of making a static variable?
Why do we prefer making external variables in multifunction programs? The book says that else it gets initialized very late. I don't get it.
Problem is that in C static can have different meanings. I will try to give an overview of the different situations in the following paragraphs.
If a variable is defined outside a function, it can be used by all functions in the file. Sometimes also called 'global variable'. This means that there is only one instance of this variable for the whole file. Also the name of the variable is stored in the resulting .OBJ file. This latter is important, since if another file also defines a variable with the same name outside a function, the linker assumes that it's the same variable in both cases, and merges them.
To make this extra clear, it's best to add the keyword "extern" to one of the variables. In this case, we say that we declare the variable, instead of defining it. It is an extra signal for the compiler/linker to indicate that we actually want to refer to a global variable defined somewhere else.
If you want to define a global variable, but don't want to make it available to other files, add the keyword static before. The keyword static tells the compiler that the variable name must not be stored in the .OBJ file. This means that two .C files with the following line:
static long MyGlobalVariable;
will each have their own variable. Both variables will be called MyGlobalVariable.
If you define a variable inside a function, it becomes a local variable. It comes into existence if the function is called, and disappears again after the function is finished.
In some situations you want to keep the value of the variable in between function calls. You could do this by using a global variable (instead of a local variable) but then the variable becomes available for all functions in the file, which you don't necessarily want. In that case you can put the keyword static before the variable, like this:
void MyFunction()
{
static long MyLocalVariable = 0;
++MyLocalVariable;
}
The first time the function is called, MyLocalVariable will be 'created' and initialized with the value 0. At the end of the function, the variable is not destroyed, but kept. So the next time you call this function, the value of the variable will be 1, not zero.
In C it really doesn't matter whether you put the variable outside the function (as global variable) or define it as static inside the function. The only difference is where the variable can be accessed.
In C++, things are quite different. If you write this (outside a function):
MyClass MyGlobalVariable;
MyGlobalVariable will be constructed (this is: the constructor will be executed) at the start of the application, before even main is called. However, you don't have real control over the order in which all global variables are constructed.
So if another file contains this:
MyOtherClass MySecondGlobalVariable;
You can't know for sure whether MyGlobalVariable or MySecondGlobalVariable is constructed first. This can give problems if the constructor of one of them relies on the presence (construction) of the other one.
On the other hand, if you define the variable as static inside a function:
void MyFunction()
{
static MyClass MyStaticVariable;
}
Then MyStaticVariable will be constructed the first time the function is called. With this construction, you can write something like this:
MyClass &getMyClass()
{
static MyClass MySelf;
return MySelf;
}
And we have implemented a singleton where we have control on when it is constructed. The first time we need it, it's constructed.
To be honest, this approach is a rather simplistic one, because it may lead to problems in multi-threaded applications. In that case, there are other tricks.
"Static" more or less means "this will always exist". Depending on the context, you get different results:
static int global_variable;
void function()
{
static int global_function_variable;
}
class foo
{
static void function()
{
static int foo_function_variable;
//...
}
static int foo_variable;
}
global_variable - Only ever visible within the "translation unit". (Since headers are more or less copied in, does this mean a static global in a header exists as separate variables for all cpp files it's included in?)
global_function_variable is created the first time function is called, and will continue to exist throughout the program's lifetime. The value persists, so if you change it in one function call, the next function call will use the changed variable.
foo::function() is a function that can be called like a global function; you don't need to have an instance of foo to call it. This means it doesn't have a valid this pointer, however. Similarly, foo_variable exists even when there aren't any foo objects. All foo objects have the same foo_variable - if you change it in one object, all other objects "see" the change.
foo_function_variable behaves, I think, just like global_function_variable.
The basic idea behind extern is to control the linkage of a variable:
From MSDN :
// specifying_linkage1.cpp
int i = 1;
void other();
int main() {
// Reference to i, defined above:
extern int i;
}
void other() {
// Address of global i assigned to pointer variable:
static int *external_i = &i;
// i will be redefined; global i no longer visible:
// int i = 16;
}
extern int global_variable;
extern can also be used to link a variable using another language, most commonly, C.
global_variable is the most common usage of extern; it says that elsewhere, there's a variable called "global_variable", and we're going to be using that variable. Somewhere, you need to declare the variable without the extern keyword, or it is never actually created.