How can a function in C maintain it's internal state?
For example strtok() - when calling strtok(NULL, del) the function continue working on a previous string.
It contains internal variables to keep track of things, declared as static. This is also the very reason why such functions aren't safe to use in multi-threaded programs.
This is done by declaring local variables as static:
unsigned int some_state_function( void )
{
static unsigned int internal_state = 0; // keeps track of the number
... // of times the function has been
return internal_state++; // called - useless, but illustrative
}
The variable internal_state has static storage duration, meaning storage for it is allocated and initialized at program startup and held until the program terminates; its lifetime extends beyond the lifetime of the function. In this case the initialization is redundant (static objects are initialized to 0 or the equivalent), but it's there to illustrate the concept - the initialization occurs once, at program startup, not when the function is called.
However, the identifier internal_state is local to some_state_function - it's not visible outside the function.
strtok does something similar - it has a local static pointer that keeps track of the string you're processing.
(C beginner alert)
Wikipedia define a static variable as, ".... a variable that has been allocated statically—whose lifetime or "extent" extends across the entire run of the program. "
Then it goes on to give an example in C:
#include <stdio.h>
void func() {
static int x = 0;
/* x is initialized only once across four calls of func() and
the variable will get incremented four
times after these calls. The final value of x will be 4. */
x++;
printf("%d\n", x); // outputs the value of x
}
int main() { //int argc, char *argv[] inside the main is optional in the particular program
func(); // prints 1
func(); // prints 2
func(); // prints 3
func(); // prints 4
return 0;
}
Here's my issue: variable x, when defined as static, doesn't hold its value for the entire run of the program. In fact, it does quite the opposite, namely, for any subsequent call of func(), it has the value it was assigned in the previous calling. It's only when I remove the static keyword that x retains its value of 0 no matter how many times func() is called.
So:
1) Is Wikipedia's explanation inaccurate/misleading, and if so, how would you better explain the nature of a static variable?
2) What is actually happening under the hood on the second and subsequent calls of func() such that the initialization of x to 0 is effectivey being ignored?
You simply misunderstand the quoted explanation. What it means to say that a variable's "lifetime" extends to the whole program is that it is allocated in memory once, initialized once, and any changes made to it are reflected at the same memory location--that memory is allocated for the life of the program. Subsequent calls to the function will find the contents of that memory (the value of x) as they left it. They are still allowed to change the value, but it will always be the same piece of memory.
When you remove the "static", you're telling the compiler to allocate a new variable "x" each time the function is called, assign it 0, and discard it when the function returns. On the next call, an entirely different variable X will be created, assigned 0 again, and discarded again. This variable's "lifetime" is thus only inside the function.
This is an entirely separate concept from the variable's "scope", which is who can see and change the variable: it's scope is still inside the function, even when static.
The local static variables are located in the .bss section along with the global ones. So their initialization is effectively "taken out" of the function and moved to the same place where global statics are initialized. So, basically, declaring some variable as local and static in some function is only limiting it's scope to this function, but by other means it is not different from any other static variable.
The Wikipedia entry is neither misleading nor incorrect; it says the variable's lifetime extends across the lifetime of the program (even before func is called), which is exactly the case. A single instance of x is created and initialized once at program startup and will persist until the program exits, retaining the last value written to it from each call to func. Think of it as a "global" variable, but only visible from within func.
If you remove the static storage class qualifier, then x only exists for the lifetime of func; each call to func creates a new instance of x, which is initialized to 0.
In c, let us say I have the following code:
int func(){
char* s = "bla";
}
I am not sure as to what this is compiled.
Since s isn't static, it doesn't survive after func() ends so it seems that the pointer to "bla" is lost.
On the other hand, the program should still know the address to "bla" so the next time func() is called, s will get the same address.
I wonder if the above code is ok or if I must declare s as static?
It is not clear how you are going to use this local pointer. Nevertheless the address of the string literal will be the same. It does not depend on how many times the function will be called. This string literal has static storage duration. So the pointer will be initialized with the same address each time when the function gets the control. There is no need to declare the pointer itself as static unless you change its initial value and want that it would be stored in the pointer between function's calls.
What is the difference between a variable declared as an auto and static?
What is the difference in allocation of memory in auto and static variable?
Why do we use static with array of pointers and what is its significance?
AUTO (default), Static, Extern & Register are the 4 modifiers for a variable in C.
auto : The default storage-class for a C variable. (i.e. no need to explicitly specify auto).
static : Changes the lifetime of the variable. (retains the scope, no
change).
This means, during runtime, the OS does NOT of delete the variable from memory once the function( containing the variable exits) and initialise the variable every time the function is called.
Rather the static variable is initialised ONLY the first time the function (containing it is called). Then it continues to reside in the memory until the program terminates.
in other words STATIC effectively makes a variable GLOBAL in memory, but with only LOCAL access.
Where your statics are stored depends on if they are 0 initialized or not.
0 initialized static data goes in .BSS (Block Started by Symbol),
non 0 initialized data goes in .DATA
One must note that, though static-variables are always in the memory, they can only be accessed ONLY from the local scope (function they are defined in).
extern : Used to signal to the compiler that the extern-definition is simply a placeholder, and the actual definition is somewhere else. Declaring a variable as extern will result in your program not reserving any memory for the variable in the scope that it was declared. It is also common to find function prototypes declared as extern.
register : Signals the compiler to Preferrably used a CPU-register (and not RAM) to store this variable.
Used to improve performance, when repeated access to the variable is made (for ex: loop counter variables).
I'll assume if you're talking about auto variables you probably mean local variables in a function. auto is the default, it means the variable is allocated on the stack when the function is called and deallocated when the function returns. static means the variable is allocated once the first time the function is called, and stays allocated for the rest of the program. This means:
int foo() {
static int x = 0;
return x++;
}
printf("%d\n", foo()); // Outputs 0
printf("%d\n", foo()); // Outputs 1
printf("%d\n", foo()); // Outputs 2
When declaring an array in C like this:
int array[10];
What is the initial value of the integers?? I'm getting different results with different compilers and I want to know if it has something to do with the compiler, or the OS.
If the array is declared in a function, then the value is undefined. int x[10]; in a function means: take the ownership of 10-int-size area of memory without doing any initialization. If the array is declared as a global one or as static in a function, then all elements are initialized to zero if they aren't initialized already.
As set by the standard, all global and function static variables automatically initialised to 0. Automatic variables are not initialised.
int a[10]; // global - all elements are initialised to 0
void foo(void) {
int b[10]; // automatic storage - contain junk
static int c[10]; // static - initialised to 0
}
However it is a good practice to always manually initialise function variable, regardless of its storage class. To set all array elements to 0 you just need to assign first array item to 0 - omitted elements will set to 0 automatically:
int b[10] = {0};
Why are function locals (auto storage class) not initialized when everything else is?
C is close to the hardware; that's its greatest strength and its biggest danger. The reason auto storage class objects have random initial values is because they are allocated on the stack, and a design decision was made not to automatically clear these (partly because they would need to be cleared on every function call).
On the other hand, the non-auto objects only have to be cleared once. Plus, the OS has to clear allocated pages for security reasons anyway. So the design decision here was to specify zero initialization. Why isn't security an issue with the stack, too? Actually it is cleared, at first. The junk you see is from earlier instances of your own program's call frames and the library code they called.
The end result is fast, memory-efficient code. All the advantages of assembly with none of the pain. Before dmr invented C, "HLL"s like Basic and entire OS kernels were really, literally, implemented as giant assembler programs. (With certain exceptions at places like IBM.)
According to the C standard, 6.7.8 (note 10):
If an object that has automatic
storage duration is not initialized
explicitly, its value is
indeterminate.
So it depends on the compiler. With MSVC, debug builds will initialize automatic variables with 0xcc, whereas non-debug builds will not initialize those variables at all.
A C variable declaration just tells the compiler to set aside and name an area of memory for you. For automatic variables, also known as stack variables, the values in that memory are not changed from what they were before. Global and static variables are set to zero when the program starts.
Some compilers in unoptimized debug mode set automatic variables to zero. However, it has become common in newer compilers to set the values to a known bad value so that the programmer does not unknowingly write code that depends on a zero being set.
In order to ask the compiler to set an array to zero for you, you can write it as:
int array[10] = {0};
Better yet is to set the array with the values it should have. That is more efficient and avoids writing into the array twice.
In most latest compilers(eg. gcc/vc++), partially initialized local array/structure members are default initialized to zero(int), NULL(char/char string), 0.000000(float/double).
Apart from local array/structure data as above, static(global/local) and global space members are also maintain the same property.
int a[5] = {0,1,2};
printf("%d %d %d\n",*a, *(a+2), *(a+4));
struct s1
{
int i1;
int i2;
int i3;
char c;
char str[5];
};
struct s1 s11 = {1};
printf("%d %d %d %c %s\n",s11.i1,s11.i2, s11.i3, s11.c, s11.str);
if(!s11.c)
printf("s11.c is null\n");
if(!*(s11.str))
printf("s11.str is null\n");
In gcc/vc++, output should be:
0 2 0
1 0 0 0.000000
s11.c is null
s11.str is null
Text from http://www.cplusplus.com/doc/tutorial/arrays/
SUMMARY:
Initializing arrays. When declaring a
regular array of local scope (within a
function, for example), if we do not
specify otherwise, its elements will
not be initialized to any value by
default, so their content will be
undetermined until we store some value
in them. The elements of global and
static arrays, on the other hand, are
automatically initialized with their
default values, which for all
fundamental types this means they are
filled with zeros.
In both cases, local and global, when
we declare an array, we have the
possibility to assign initial values
to each one of its elements by
enclosing the values in braces { }.
For example:
int billy [5] = { 16, 2, 77, 40, 12071 };
The relevant sections from the C standard (emphasis mine):
5.1.2 Execution environments
All objects with static storage duration shall be initialized (set to their initial values) before program startup.
6.2.4 Storage durations of objects
An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration.
6.2.5 Types
Array and structure types are collectively called aggregate types.
6.7.8 Initialization
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
if it has pointer type, it is initialized to a null pointer;
if it has arithmetic type, it is initialized to (positive or unsigned) zero;
if it is an aggregate, every member is initialized (recursively) according to these rules;
if it is a union, the first named member is initialized (recursively) according to these rules.
It depends from the location of your array.
if it is global/static array it will be part of bss section which means it will be zero initialized at run time by C copy routine.
If it is local array inside a function, then it will be located within the stack and initial value is not known.
if array is declared inside a function then it has undefined value but if the array declared as global one or it is static inside the function then the array has default value of 0.