Why is the output of the following two segments different? - c

#include <stdio.h>
int main()
{
static int i = 5; // here
if (--i){
printf("%d ", i);
main();
}
}
Output: 4 3 2 1
#include <stdio.h>
int main()
{
int i = 5; // here
if (--i){
printf("%d ", i);
main();
}
}
Output: 4 4 4 4... (Segmentation fault)
Any idea how static int variable is taken into account only once and int is taken over and over again?

When you declare a static variable in a function, the function "remembers" the last value of the variable even after it terminates.
void Foo() {
static int x = 5;
}
In the example above, you are telling the compiler that x shall be "remembered" and has an initial value of 5. Subsequent calls to Foo() does not reassign x a value of 5, but uses the previously remembered value.
In contrast:
void Bar() {
int x = 5;
}
Here, you are telling the compiler that everytime Bar() executes, a new variable x is to be created on the stack and assigned a value of 5.

A variable declared as static inside of a function retains its value each time the function is called. It is initialized only once, when the function is first called. So when the function calls itself the value of i is retained from the prior call.
A local variable that is not static is specific to a given call of a function, so each time the function is called a new copy of the variable is created and initialized. This results in i being 5 each time, which in turn results in infinite recursion leading to a stack overflow and a core dump.

Related

If a variable is defined previously and is waiting on a function to return a value, what is the value of that variable?

This is for programming in C.
Say I had the follow code in my program:
int fun1(int x);
int main (void)
{
int a = 5;
a = fun1(10);
}
int fun1(int x)
{
\\Program arbitrarily ends here
return x;
}
In my memory diagram what would the value of a be assuming the program terminates before fun1 is able to return a value? Would the value of a be undetermined (??) or would it be 5?
The value of a is already initialized to 5. Now, according to the condition, you want to know the results of that circumstance when the fun1() ends before it could return a value; assume the following:
int fun1(int x)
{
// return x;
}
Here we've supposed the function quits before returning the value.
You'll still get the output 5 before, during or after execution of the program since it returns nothing but the variable a is preassigned to 5 and it can't be changed to 10 unless the function returns 10 and assigns to the variable.
But remember, if you don't assign anything to a, then it may show an unexpected value (I got 4195638 when used printf() for a).

Not understanding the function of static int in C

I'm trying to understand this piece of code, but I don't know why the amount of a static variable sometimes changes and sometimes not.
#include <stdio.h>
int func1 (int x)
{
extern int a;
static int y=0;
printf("%d\n%d\n",a,y);
a=x+5; y=x+1;
{int y=10; printf("%d\n",y);}
return y;
}
int a;
int main()
{
a=func1(1);
printf("%d\n",a);
{
int a=1;
printf("%d\n", a);
}
a=func1(a);
printf("%d",a);
return 0;
}
Here is the output:
0
0
10
2
1
2
2
10
3
At first, when a = func(1) is run, y is declared as 0 and then changes to 2 and it prints 2. But when it runs a = func(a) when a is 2, I expected that y will become 0 through static int y = 0 but y doesn't change. Why it doesn't happen?
A static object is initialized, conceptually, when it is created.
The lifetime of a static object begins when the program starts executing and continues until execution ends.
So, when the program starts executing, y is initialized to 0. After that, its value changes only when it is modified, as with assignment statements. The statement that defines it, static int y = 0;, does not modify it after the initialization.
Variables declared as static inside of a function retain their value through the lifetime of the program, even when the variable name goes out of scope. The initializer for a static variable is only applied at program startup.
So when the program starts, y is initialized to 0. Then in the first call to func it sets y to 2. This value is retained even after the function exits. So when func is called a second time, y is still 2 when the function starts.
static means you have only one shared value of the variable, you can imagine it declared as a global variable keeps its value between multiple function calls.
First times you called the funct1 with x = 1 so y returned as 2.
The next time you called the function func1 with x = 2, the value of y will not be declared again but will use the last value of last call (y=2), and update it with y = x + 1 to be 3.
TLDR;
Read the static declaration of a variable only once (static int y = 0), and do not back to it again, use the last value of it next times.

Automatic Storage class

Automatic Storage used in a function does not re-initialize the i variable declared using the auto keyword.
Practice.c : main() and func() are in the Practice.c
#include <stdio.h>
main()
{
func();
func();
func();
}
func()
{
auto int i=1;
printf(" i = %d",i);
i=i+1;
}
After compilation when I execute Practice.exe the output is as follows :
i = 1
i = 1
i = 1
Every time main() calls func() i is re-initialized to 1. This is correct as scope of i is within the func() block, and when the control comes out of this block the value of i is lost. So, when I will be calling this func() function for the second time the value of i will be re-initialized to 1.
Check the following New.c Program.
New.c : contains both main() & func()
#include <stdio.h>
main()
{
func();
func();
func();
func();
func();
func();
func();
func();
}
func()
{
auto int i;
printf(" i = %d",i);
i=i+1;
}
Just to be sure, I called the function func() 8 times.
But in New.c, i is not initialized. When I executed this program after compilation, the output of it is as follows :
i = 4201582
i = 4201583
i = 4201584
i = 4201585
i = 4201586
i = 4201587
i = 4201588
i = 4201589
The output shows increment on every call. What is the exact reason behind this ?
The output shows increment on every call. What is the exact reason
behind this ?
Variables with automatic storage allocation are not initialized by default and it is undefined behaviour to access an uninitialized variable. This means the behaviour of your second program cannot be reasoned out.
Also, note that the default stororage class of variables in function scope is automatic. Therefore, you don't need the auto keyword to qualify the definition of i.
// in function scope
auto int i;
// equivalent to
int i;
Also, it's wrong to say
So, when I will be calling this func() function for the second time
the value of i will be re-initialized to 1.
The variable i is not re-initialized. It goes out of scope once the function containing it returns. When the function is called again, it's again allocated on the stack. This does not mean that it is allocated on the same memory address.
Also, you need to take care of the return type and parameter list of the functions. The implicit return type is int and empty parameter list means no information is available about the number and type of arguments which means the function takes a fixed but unknown number of arguments of unknown type. You should always explicitly mention void in the parameter list to mean that the function takes no argument.
#include <stdio.h>
// prototype of the function func
void func(void);
// main should have one of the below signatures -
// int main(void); or
// int main(int argc, char *argv[]);
int main(void)
{
func();
func();
func();
}
// explicitly mention void in the
// parameter list to mean the function
// takes no argument
void func(void)
{
// using auto keyword is redundant because
// local variables have automatic storage allocation
int i = 1;
printf("i = %d", i);
i = i + 1;
}
In the second case, you make use of i without ever having initialized it.
The value is therefore undefined by the language. The fact that you see a pattern of the value incrementing is an artifact of the particular compiler you are using.
In the first iteration, you have a random-seeming value that happens to be at the memory location that i represents. Your function increments the value at that memory location, then that memory location happens to be used for subsequent calls.

Heap and Stack segment

I came across a small puzzle for which I was trying to find the output. Once I managed to get the output, I tweaked in 1 line and the output is totally different. Why does the output of the following two programs vary?:
a)
#include<stdio.h>
int fun()
{
static int num = 40;
return num--;
}
int main()
{
for(fun(); fun(); fun())
{
printf("%d ", fun());
}
getchar();
return 0;
}
Output:
38 35 32 29 26 23 20 17 14 11 8 5 2
b)
#include<stdio.h>
int fun()
{
static int num;
num = 40;
return num--;
}
int main()
{
for(fun(); fun(); fun())
{
printf("%d ", fun());
}
getchar();
return 0;
}
Output: Infinite loop printing 40 everytime
There is just one difference: The declaration and initialization are done at the same time in (a) but separately in (b). How does that effect the final outcome?
static int num = 40;
static int num;
These both get evaluated once. num does not live on the runtime stack (but rather in the data segment) Then,
num = 40;
gets evaluated every time you call fun(). You're reassigning a variable that was declared outside the stack to 40, causing it to loop forever.
In the first one, num will only be initialised to 40 the first time the function is called. In the second one, it is set to 40 every time the function is called.
first one, num gets initialized once, no matter how many times you call the function
second one, num gets set to 40 every time you call the function
Two concepts need to be looked into here
lifetime of variable
scope of variable
The lifetime of a variable is the period over which it exists. If num were defined without the keyword static, the lifetime would be from the entry into fun() to the return from fun(); so it would be re-initialized to 40 on every call.
The scope of variable is where the variable name can be seen. Here, num is visible only inside function fun().
The keyword static is used to extend the lifetime of a variable to the lifetime of the program. In case of static declaration initialization occurs only once and then the variable retains its value inside the routine fun(). So if you are overwriting it by setting it to value of 40 in the second case its values keeps getting set to 40 on every call to fun(). The declaration of the variable num as static is redundant in your second code.

Why uninitialized local variable always has the same initial value?

In this piece of code, why in my testing the result is always 1, 2, and 3?
#include <stdio.h>
void test() {
int a;
a++;
printf("%d",a);
}
int main(int argc, char *argv[]) {
test();
test();
test();
}
I think the variable in test() is static, isn't it? And Why?
The variable is not static. You're accessing an uninitialized variable. The behavior is undefined.
As other answers told, your variable is not initialized.
It prints 1, 2 and 3 possibly because of your compiler compiled the code with prolog(prologue) that cleans the stack with zeros.
The local variables in C, actually point to the offset on your stack, and the stack frame will be restored after the call is returned.
I googled and selected a artical randomly that told about this, see [How function calls work?].
Here is a video talk about that [Assembly Programming Assembly Function Stack Frame Explained ] (again, selected randomly).
And Wikipedia explains the [Call stack] as well.
Because you are working with an unintialize value... (random behaviour in this case).
Initialize your variable (example to 0) :
#include <stdio.h>
void test(){
int a=0;
a++;
printf("%d",a);
}
int main(int argc, char *argv[]) {
test();
test();
test();
}
No, your variable is not static at all!
https://stackoverflow.com/a/1597426/1758762
Static variables (file scope and function static) are initialized to zero:
int x; // zero
int y = 0; // also zero
void foo() {
static int x; // also zero
}
Non-static variables (local variables) are indeterminate. Reading them prior to assigning a value results in undefined behavior.
void foo() {
int x;
printf("%d", x); // the compiler is free to crash here
}
the variable you are trying to print is not static and neither it is initialized , thus it is taking garbage value , which seems random to you , if you execute this program on a different machine ,then there you will have different output because there you will have different garbage value
in order to avoid it , you will have to initialize your variable with some value

Resources