4bh1
4bh1

Reputation: 182

C local variable reused

As much as I know after every function call the local variables are discarded. But when I executed this piece of code the variables retain their previous value. What is this behavior?

Compiler: gcc 4.8.4

#include<stdio.h>
void t();
int main(void){
    t();
    t();
    t();
    return 0;
}

void t(){
    int i;
    i++;
    printf("%d\n",i);
}

Output:

4bh1@mybox:~/C-fi$ ./test 
1
2
3

Upvotes: 0

Views: 756

Answers (3)

Luis Perez
Luis Perez

Reputation: 28120

It's the stack man

In this particular case it probably has to do with the how memory is allocated on the for the variables in a function.

There is a continuous block of memory that is reserved for function variables called the stack.

When you call a function a portion of the stack is reserved for that function and that's where the value for the variables in that function are stored.

When you exit the function that portion in the heap is not reserved anymore and will be used by the next function that is called. BUT, the values in it are not zero'd out, the values remain there.

So in this case if you don't initialize your function variables it's going to contain whatever happen to be in the stack.

In this case since you are calling the same function over and over again what's going to be left over is going to be predictable. But in most circumstances you are going to have issues and it won't be predicable.

For example if you call a different function in between.

Breaks when calling a different function in between

#include<stdio.h>
void t();
void otherFunction();
int main(void){
    t();
    otherFunction();
    t();
    t();
    return 0;
}

void t(){
    int i;
    i++;
    printf("%d\n",i);
}

void otherFunction(){
    int x = 10;
}

Output:

1
11
12

It also wouldn't behave the same if x() were called deeper in the stack:

Breaks when called from different depth in the stack

#include<stdio.h>
void t();
void callT();
int main(void){
    t();
    callT();
    t();
    t();
    return 0;
}

void t(){
    int i;
    i++;
    printf("%d\n",i);
}

void callT(){
    t();
}

Output:

1
1
1
2

Talk about undefined behaviour, I can't even explain that.

It get's worse in our examples were using int or nothing in our functions. The stack doesn't know what kind of data is in the stack it's just a bunch of bytes. So you can end up with a situation where the data was incorrectly interpreted into another type.

For example say one of the functions used a float instead of a int.

Breaks when different types are used

#include<stdio.h>
void t();
void assignFloat();
int main(void){
    t();
    assignFloat();
    t();
    t();
    return 0;
}

void t(){
    int i;
    i++;
    printf("%d\n",i);
}

void assignFloat(){
    float x = 10;
}

Output:

1
1092616193
1092616194

This is not the behaviour you are always going to get, the behaviour is "undefined" which means that you can't predict the behaviour from compiler to compiler or even from one compiler configuration to another. Undefined means it's unreliable and you shouldn't do it.

The examples in this answer were tested using:

g++ (GCC) 5.3.1 20151207 (Red Hat 5.3.1-2)

Using the online tool:

http://www.tutorialspoint.com/compile_cpp_online.php

Upvotes: 3

NathanOliver
NathanOliver

Reputation: 180630

The behavior of your program is undefined. i is uninitialized so any use of i besides setting its values is undefined behavior.

Most likely what you are seeing is i gets the same "stack space" allocated to it each time so you are just reusing the previous value.

Do note that when an int(or any type) goes out of scope the compiler does not reset it value to something as that would be wasted cpu cycles. This is why you can see the value increasing as it is just reusing what was in the memory space.

Upvotes: 15

Daniel Kravetz Malabud
Daniel Kravetz Malabud

Reputation: 783

You should initialize your variable i . You could also use void for the signature of t().

Here's an updated version (also took the liberty of using %d with printf):

#include<stdio.h>
void t(void);
int main(void){
t();
t();
t();
return 0;
}

void t(void){
int i = 0;
i++;
printf("%d \n",i);
}

Upvotes: 0

Related Questions