threads : variable allocated on the stack is persisting

I always thought variables allocated on the stack vanish when the function returns / ends
However, using threads, I am seeing my variables persist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// I only post portions of the very long code

// the input function called by below ev_init as argument
static int input_callback(int fd, short revents, void *data) {
 struct input_event ev;
 process_input(fd, ev);
 ...
}


// an input thread that will call back above function through ev_dispatch()
static void *input_thread(void *cookie)
{
    for (;;) {
        if (!ev_wait(-1))
            ev_dispatch();
    }
    return NULL;
}


// init function creating above input thread and calling back input_callback function
ui_init() {
    ev_init(input_callback, NULL)
    pthread_t t;
    pthread_create(&t, NULL, input_thread, NULL);
}


// ev_init calling the input function
int ev_init(ev_callback input_cb, void *data) {
...

}


// the ev_dispatch function called by input thread
void ev_dispatch(void)
{
    unsigned n;
    int ret;

    for (n = 0; n < ev_count; n++) {
        ev_callback cb = ev_fdinfo[n].cb;
        if (cb && (ev_fds[n].revents & ev_fds[n].events))
            cb(ev_fds[n].fd, ev_fds[n].revents, ev_fdinfo[n].data);
    }
}



Well, the code is not mine, I am just working on it and customizing it
My question is:

My process_input(fd, ev) function can be simplified to my issue:

1
2
3
4
5
6
7
8
9
10
11
12
static int process_input(fd, ev) {
    static int stack_var = 0;
    if (condition1 == true)
        stack_var = 1;
    else if (condition2 == true)
        stack_var = 0;

    if (stack_var)
        return good_catch;
    else
        return not_matched;
}


Now, starts my surprise:
process_input(fd, ev) function will be recursively called by input_callback() through input thread to process events. However, stack_var will not be initialized to zero on each call. The result from previous call will persist. That is, if I call it first time and condition1 is true, stack_var is set to 1.

Now, on second call if condition1 and condition2 are false, I will still have my stack_var == 1 and I get a good_catch

I added many logging code to track changes to stack_var which is only static inside function without any external occurance and I could confirm it clearly

Is this expected behaviour when calling threads that way?
Last edited on
Any idea?
> However, stack_var will not be initialized to zero on each call.

stack_var has a static storage duration.

See: http://en.cppreference.com/w/cpp/language/storage_duration
Thank you,
It seems I am missing a basic thing here !
In fact, I tried this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static int loop_function() {
    static int stack_var = 0;
    stack_var++;
    printf("stack_var=%d\n", stack_var);
    return 0;
}

int main() {
    int i;
    for(i=1; i<6; i++) {
        loop_function();
    }
    return 0;
}

# output
stack_var=1
stack_var=2
stack_var=3
stack_var=4
stack_var=5


And my stack_var loops from 1 to 5
So, if I undertsand it well. In c++:

1- The static variables declared into a function persist in memory when function ends
2- They are only accessible inside the function obviously
3- They will be removed only when main() function exits

Am I right?
Last edited on
Yes, you're right. That's the whole point of a static variable - they persist even when out of scope.
Thank you
It is clear now
> 1- The static variables declared into a function persist in memory when function ends
> 3- They will be removed only when main() function exits

Yes.


> 2- They are only accessible inside the function obviously

No. They are part of the static data area of the program, which exists till the program ends. The name of the variable is not programmatically visible outside the local scope; but the variable can be aliased and accessed.

1
2
3
4
5
6
7
8
9
const int* global = NULL ;

void  foo()
{
     static int local = 7 ;
     global = &local ; 

     // ...
}


After foo is called, the integer can be accessed through the name global.
But the name local is programmatically visible only within the function.
Thank you for this even helpful input
I always got used to initialize my variables outside the function if needed, so never had to think at this static variable inside a function except in some internal loops to avoid initialization many times

Was it always like this in C++ for static variables inside a function?
No. They are part of the static data area of the program, which exists till the program ends. The name of the variable is not programmatically visible outside the local scope; but the variable can be aliased and accessed.

Good point - thanks for the extra clarification.

Was it always like this in C++ for static variables inside a function?

Yes, static variables in functions were a feature of C when I started programming in it 20 years ago.
Topic archived. No new replies allowed.