简体   繁体   中英

C - Why my variable is not destroyed?

I discover C language (I am from javascript), I have this simple kind of script

#include "stdio.h"

int rand(){
  int numb;
  for (int i = 0; i < 4; ++i)
  {
    numb++;
  }
  return numb;
}

int main(int argc, char const *argv[])
{
  int a = rand();
  int b = rand();
  printf("%i , %i\n", a, b);
  return 0;
}

My question is why am I obtaining the same result (4,8) as if the variable were declarated as static & initialized to 0 ?

static int numb = 0;

I am not really sure about understand very well the scope of variables :s

Thanks !

The program has undefined behavior because the local variable numb is not initialized and in general has indeterminate value.

The result you have is explained the following way. It seems that when the function was called the first time the memory allocated for the variable stored zeroes.

When the function was called the second time it occurred so that the function used the same memory for the variable with the automatic storage duration though in general it is not necessary that the same address for the variable will be used.

According to the C Standard (6.2.4 Storage durations of objects)

1 An object has a storage duration that determines its lifetime. There are four storage durations: static, thread, automatic, and allocated...

and

6 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration or compound literal is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached .

And at last (J.2 Undefined behavior)

— The value of an object with automatic storage duration is used while it is indeterminate (6.2.4, 6.7.9, 6.8).

My question is why am I obtaining the same result (4,8) as if the variable where declared as static & initialized to 0 ?

It is undefined behaviour (UB). Your observation is mere coincidence. Compile it with another compiler or on a different architecture and the results may differ.

You have to initialize the integer in the function yourself.

When you call rand() , the numb variable is allocated on the data stack and the stack pointer is increased.

When the function is over and you return to main , the allocated data stack is released, and the stack pointer is decreased (the value on the actual memory remains intact).

When you recall rand() , the numb variable is again allocated on the data stack, on its previous location. It is not initialized, so the previous value is still there...

For downvoters: it is all in the C standard.

3 different cases

1.Undefined behaviour

int foo(){
  int numb;
  for (int i = 0; i < 4; ++i)
  {
    numb++;
  }
  return numb;
}

UB - nothing to explain. Anything can happen

2.Automatic initialised variable

int foo(){
  int numb = 0;
  for (int i = 0; i < 4; ++i)
  {
    numb++;
  }
  return numb;
}

numb is initialised to zero every time the function is called and destroyed on exit.

3.Static initialised variable

int foo(){
  static int numb = 0;
  for (int i = 0; i < 4; ++i)
  {
    numb++;
  }
  return numb;
}

The variable is initialised only one time and keeps its value. The scope of static automatic variables is identical to that of automatic variables, ie it is local to the block in which it is defined - in this case the function foo , but the value is kept during the program lifetime. Those variables are initialised only once, and keep their value between the calls. if the static automatic variable is not initialised - it will be initialised during the startup procedures to the default value - which is implementation defined (exept the initial values)(usually the .bss segment and initialised to zero).

source: C standard

All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified.

-

An object whose identifier is declared without the storage-class specifier _Thread_local, and either with external or internal linkage or with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

-

All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM