I'm reading a C programming book, The C Programming Language (K & R, 2nd Edition). I got to know the facts about external variables in the book, but I found something different when I practiced the principles by myself. The book says:
"... because external variables remain in existence permanently, rather than appearing and disappearing as functions are called and exited, they retain their values even after the functions that set them have returned."
However, when I code like this:
#include <stdio.h>
int i = 0;
void foo();
main()
{
foo();
printf("%d", i);
return 0;
}
void foo()
{
i = 1;
}
The program prints 1 instead of 0 which is the original value of the external variable i. So I wonder where I get mistakes while thinking about the principle and how to understand it.
...they retain their values even after the functions that set them have returned.
I'm guessing it's a question of interpretation on your part.
Given that the variable is global, every time you change it, in any function, it will assume and retain that value until it is next modified.
Take the function:
int i = 0;
void foo();
int main()
{
int x = 0;
foo(x);
printf("%d", i);
printf("%d", x);
return 0;
}
void foo(int x)
{
x = 1;
i = 1;
}
result: x = 0 i = 1
x is passed by value, essentially, a copy of it, so as soon as the function goes out of scope, i.e. returns, the copy is discarded. i is global so you don't even need to pass it; every function is aware of its existence and will change its value.
Opposite to what you think this phrase
...as functions are called and exited, they remain their values even
after the functions that set them have returned
means that after exiting a function a variables with the external linkage keeps the value assigned to it in the function. And your program demonstrates this.
Pay attention to that now according to the C Standard the function main without parameters shall be declared like
int main( void )
There is no default type int of a function though some compilers keep the backward compatibility.
I'm getting this error while trying to define a local static variable.
Initializer element is not constant.
I want to retain the first value of var inside this recursion. How to pass this?
Hope you also clarify the side effects of assigning arguments to the local static variables to be prevented.
int function(int var)
{
static int index=var;
//some code ...
return var==0?1:function(var-1);
}
the static variable is initialized before the function even starts. It's like a global variable, only with function scope. The compiler cannot use a value that it doesn't know yet.
You could workaround this with an helper boolean:
int function(int var)
{
static int index_is_set=0;
static int index;
if (!index_is_set)
{
index = var;
index_is_set = 1;
}
//some code ...
return var==0?1:function(var-1);
}
so first time you enter the function it sets the value, sets the boolean flag to 1 so it's not overwritten by further calls.
note that this isn't very useful as a construct, since if you are to call your function recursively a second time in your program (after having obtained the result the first time, I mean), there's no way to reset the variable (unless you make index_is_set global so you can reset it from the outside).
Note that it is possible to get rid of all this static thing altogether by using the start value as an extra parameter.
int function(int var, int start_value)
{
// ...
return var==0 ? 1 : function(var-1,start_value);
}
First call goes like:
function(20,20);
or wrapped in a function which hides this implementation:
int function_wrapper(int var)
{
return function(var,var);
}
the start value is passed along all calls. Consumes a bit more auto variable space, but is much cleaner, no memory effect & easier to debug.
The case:
static int index=var;
Is a declaration with initializer (see ISO/IEC 9899:2011 §6.7 Declarations). The statement declares a static variable initialized to a value that must be a constant defined at compile time. In plain word because the value is initialized before the execution starts the initializer must be defined before function usage.
If you want retain the first value of a recursion the way you are using isn't a good choice for many reasons:
The value, as seen, cannot be assigned using a not constant value
If it worked, the next time you enter the function it would be reassigned clearing the very first value
A local static variable has unlimited life, but scope limited to the local function. Then you cannot access or initialize it from external scopes.
a solution can be to pass to the function 2 variables a first value and the value passing the same value the very first call of the function:
int function(int first_var, int var)
{
//some code ...
return var==0?1:function(first_var, var-1);
}
...
function(5, 5); //First call
For sake of completeness it could work by breaking your statement in a definition of the static variable without initialization (or with a generic initialization), followed by an assignment (ISO/IEC 9899:2011 §6.5.16 Assignment operators):
int function(int var)
{
static int index; //Declaration
index=var; //Assignement
//some code ...
return var==0?1:function(var-1);
}
But because it will be reassigned each time the function reenters, it is only a big nonsense...
In my code below variable1 is only being initialized to 0 in the very first call. My concern is that in every recursive call static variable1; is being declared. Will this cause problems with keeps track of the numbers? Or does the compiler know to skip over the declaration in each recursive call?
My code:
void funtion1(numberOfTimesCalled){
numberOfTimesCalled++;
static variable1;
if(numberofTimesCalled = 0){
variable1 = 0;
}
<some processing>
variable1= variable1+1;
if(variable1<10){
function1(numberOfTimesCalled);
}
}
My concern is that in every recursive call static variable1; is being
declared.
Yes, it's safe as a variable with static storage duration will not be re-declared again. It's lifetime is entire execution of the program and is initialized only once before. So unless you intend to "reset" the value of varaible1, you don't even need the special
condition:
if(numberofTimesCalled == 0){ // assuming you intended to check with ==,
// a single = is for assignment.
variable1 = 0;
}
because a variable with static duration will be zero initialized at program startup.
This question already has answers here:
What happens to a declared, uninitialized variable in C? Does it have a value?
(9 answers)
Closed 7 years ago.
void func();
int main() {
func();
func();
func();
}
void func() {
int a;
printf("%d\n",++a);
}
When I run this C code in GCC compiler I get output as
1
2
3
Why does this happen without using the static keyword?
There are two cases to consider:
If the local variable is static, it is initialized with zeros; static variables of pointer type are set to NULL
If the local variable is automatic, it is not initialized at all. Reading from such variable without assigning to it first is undefined behavior.
According to the C Standard (6.7.9 Initialization)
10 If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate.
and (3.19.2)
1 indeterminate value either an unspecified value or a trap
representation
So there is no default value for objects with automatic storage duration. They have indeterminate values.
Take into account that the notions of local variable and of variable with automatic storage duration are different. For example in this program
#include <stdio.h>
int x = 10;
void f()
{
extern int x;
printf( "%d\n", x );
}
int main( void )
{
f();
}
the variable x declared in function f like
extern int x;
is a local variable of the function. But it has external linkage and denotes the same variable as the global. x.
The program output will be
10
This is a very simple program. A local variable is placed on the stack. No one can guarantee what value will be on the stack at the beginning of the program. But since you call the same function which increments the local variable a, the variable is incremented on the stack. Then you call the same function again so it allocates the same place on the stack which already has the value of a from the previous time. If you call any other function between func () in the int main() (for example printf), you will get different results.
What will be printed out? 6 6 or 6 7? And why?
void foo()
{
static int x = 5;
x++;
printf("%d", x);
}
int main()
{
foo();
foo();
return 0;
}
There are two issues here, lifetime and scope.
The scope of variable is where the variable name can be seen. Here, x is visible only inside function foo().
The lifetime of a variable is the period over which it exists. If x were defined without the keyword static, the lifetime would be from the entry into foo() to the return from foo(); so it would be re-initialized to 5 on every call.
The keyword static acts to extend the lifetime of a variable to the lifetime of the programme; e.g. initialization occurs once and once only and then the variable retains its value - whatever it has come to be - over all future calls to foo().
Output: 6 7
Reason: static variable is initialised only once (unlike auto variable) and further definition of static variable would be bypassed during runtime. And if it is not initialised manually, it is initialised by value 0 automatically.
So,
void foo() {
static int x = 5; // assigns value of 5 only once
x++;
printf("%d", x);
}
int main() {
foo(); // x = 6
foo(); // x = 7
return 0;
}
That is the same as having the following program:
static int x = 5;
void foo()
{
x++;
printf("%d", x);
}
int main()
{
foo();
foo();
return 0;
}
All that the static keyword does in that program is it tells the compiler (essentially) 'hey, I have a variable here that I don't want anyone else accessing, don't tell anyone else it exists'.
Inside a method, the static keyword tells the compiler the same as above, but also, 'don't tell anyone that this exists outside of this function, it should only be accessible inside this function'.
I hope this helps
6 7
compiler arranges that static variable initialization does not happen each time the function is entered
Output: 6,7
Reason
The declaration of x is inside foo but the x=5 initialization takes place outside of foo!
What we need to understand here is that
static int x = 5;
is not the same as
static int x;
x = 5;
Other answers have used the important words here, scope and lifetime, and pointed out that the scope of x is from the point of its declaration in the function foo to the end of the function foo. For example I checked by moving the declaration to the end of the function, and that makes x undeclared at the x++; statement.
So the static int x (scope) part of the statement actually applies where you read it, somewhere INSIDE the function and only from there onwards, not above it inside the function.
However the x = 5 (lifetime) part of the statement is initialization of the variable and happening OUTSIDE of the function as part of the program loading. Variable x is born with a value of 5 when the program loads.
I read this in one of the comments: "Also, this doesn't address the really confusing part, which is the fact that the initializer is skipped on subsequent calls." It is skipped on all calls. Initialization of the variable is outside of the function code proper.
The value of 5 is theoretically set regardless of whether or not foo is called at all, although a compiler might optimize the function away if you don't call it anywhere. The value of 5 should be in the variable before foo is ever called.
Inside of foo, the statement static int x = 5; is unlikely to be generating any code at all.
I found the address x uses when I put a function foo into a program of mine, and then (correctly) guessed that the same location would be used if I ran the program again. The partial screen capture below shows that x has the value 5 even before the first call to foo.
A static variable inside a function has a lifespan as long as your program runs. It won't be allocated every time your function is called and deallocated when your function returns.
Let's just read the Wikipedia article on Static Variables...
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.
Vadiklk,
Why ...? Reason is that static variable is initialized only once, and maintains its value throughout the program.
means, you can use static variable between function calls.
also it can be used to count "how many times a function is called"
main()
{
static int var = 5;
printf("%d ",var--);
if(var)
main();
}
and answer is 5 4 3 2 1 and not 5 5 5 5 5 5 .... (infinite loop) as you are expecting.
again, reason is static variable is initialized once, when next time main() is called
it will not be initialize to 5 because it is already initialized in the program.So we can change the value but can not reinitialized. Thats how static variable works.
or you can consider as per storage: static variables are stored on Data Section of a program and variables which are stored in Data Section are initialized once. and before initialization they are kept in BSS section.
In turn Auto(local) variables are stored on Stack and all the variables on stack reinitialized all time when function is called as new FAR(function activation record) is created for that.
okay for more understanding, do the above example without "static" and let you know what will be the output. That make you to understand the difference between these two.
Thanks
Javed
The output will be 6 7. A static variable (whether inside a function or not) is initialized exactly once, before any function in that translation unit executes. After that, it retains its value until modified.
You will get 6 7 printed as, as is easily tested, and here's the reason: When foo is first called, the static variable x is initialized to 5. Then it is incremented to 6 and printed.
Now for the next call to foo. The program skips the static variable initialization, and instead uses the value 6 which was assigned to x the last time around. The execution proceeds as normal, giving you the value 7.
6 7
x is a global variable that is visible only from foo(). 5 is its initial value, as stored in the .data section of the code. Any subsequent modification overwrite previous value. There is no assignment code generated in the function body.
6 and 7
Because static variable intialise only once,
So 5++ becomes 6 at 1st call
6++ becomes 7 at 2nd call
Note-when 2nd call occurs it takes x value is 6 instead of 5 because x is static variable.
In C++11 at least, when the expression used to initialize a local static variable is not a 'constexpr' (cannot be evaluated by the compiler), then initialization must happen during the first call to the function. The simplest example is to directly use a parameter to intialize the local static variable. Thus the compiler must emit code to guess whether the call is the first one or not, which in turn requires a local boolean variable. I've compiled such example and checked this is true by seeing the assembly code. The example can be like this:
void f( int p )
{
static const int first_p = p ;
cout << "first p == " << p << endl ;
}
void main()
{
f(1); f(2); f(3);
}
of course, when the expresion is 'constexpr', then this is not required and the variable can be initialized on program load by using a value stored by the compiler in the output assembly code.
Share what I learned about this point.
In C static is a declaration specifier, which falls into three categories:
storage classes: there are four classes: auto, static, extern and register.
type qualifiers: like keywords: const, volatile, etc.
type specifiers: like keywords: void, char, short, int, etc.
So static is a storage classes. It will determine the following three properties of each variable in a C program.
storage duration: means when memory is allocated for the variable and when the memory is released. A variable with static storage duration stays at the same memory location as long as the program is running.
scope: means the portion of the program text in which the variable can be accessed.
linkage: means the extent to which the variable can be shared by different parts(or files) of a program.
The static storage class has a different effect on a variable depending on it is declared outside a block or inside a block. Let's focus on the case when a static variable declared within a block(the one discussed in this post).
A static variable in a block is initialized only once.
If a function is called multiple times, the static block variable is shared by all calls of the function.
This understanding is based on the book "c programming a modern approach"