当变量超出范围时会发生什么? [英] What happens when a variable goes out of scope?

查看:21
本文介绍了当变量超出范围时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在大多数托管语言(即具有 GC 的语言)中,超出范围的局部变量不可访问且具有更高的 GC 优先级(因此,它们将首先被释放).

In most managed languages (that is, the ones with a GC), local variables that go out of scope are inaccessible and have a higher GC-priority (hence, they'll be freed first).

现在,C 不是托管语言,这里超出范围的变量会怎样?

Now, C is not a managed language, what happens to variables that go out of scope here?

我用 C 创建了一个小测试用例:

I created a small test-case in C:

#include <stdio.h>
int main(void){
    int *ptr;

    {
        // New scope
        int tmp = 17;
        ptr = &tmp; // Just to see if the memory is cleared
    }

    //printf("tmp = %d", tmp); // Compile-time error (as expected)
    printf("ptr = %d
", *ptr);

    return 0;
}

我使用 GCC 4.7.3 编译,上面的程序打印 17,为什么?什么时候/什么情况下会释放局部变量?

I'm using GCC 4.7.3 to compile and the program above prints 17, why? And when/under what circumstances will the local variables be freed?

推荐答案

您的代码示例的实际行为由两个主要因素决定:1) 行为未定义由语言,2)优化编译器将生成与您的 C 代码物理上不匹配的机器代码.

The actual behavior of your code sample is determined by two primary factors: 1) the behavior is undefined by the language, 2) an optimizing compiler will generate machine code that does not physically match your C code.

例如,尽管行为未定义,但 GCC 可以(并且将)轻松地将您的代码优化为仅仅

For example, despite the fact that the behavior is undefined, GCC can (and will) easily optimize your code to a mere

printf("ptr = %d
", 17);

这意味着您看到的输出与代码中任何变量发生的情况几乎没有关系.

which means that the output you see has very little to do with what happens to any variables in your code.

如果您希望代码的行为更好地反映物理上发生的情况,您应该声明您的指针 volatile.行为仍然是未定义的,但至少会限制一些优化.

If you want the behavior of your code to better reflect what happens physically, you should declare your pointers volatile. The behavior will still be undefined, but at least it will restrict some optimizations.

现在,当局部变量超出范围时会发生什么.没有任何身体发生.典型的实现会在程序堆栈中分配足够的空间来存储当前函数中嵌套块的最深级别的所有变量.这个空间通常在函数启动时一次性分配到堆栈中,并在函数退出时释放回来.

Now, as to what happens to local variables when they go out of scope. Nothing physical happens. A typical implementation will allocate enough space in the program stack to store all variables at the deepest level of block nesting in the current function. This space is typically allocated in the stack in one shot at the function startup and released back at the function exit.

这意味着之前被 tmp 占用的内存继续保留在堆栈中,直到函数退出.这也意味着相同的堆栈空间可以(并且将会)被同级块中具有大致相同级别的局部深度"的不同变量重用.该空间将保存最后一个变量的值,直到在某个同级块变量中声明的其他变量覆盖它.在您的示例中,没有人覆盖以前由 tmp 占用的空间,因此您通常会看到值 17 在该内存中完好无损.

That means that the memory formerly occupied by tmp continues to remain reserved in the stack until the function exits. That also means that the same stack space can (and will) be reused by different variables having approximately the same level of "locality depth" in sibling blocks. The space will hold the value of the last variable until some other variable declared in some sibling block variable overrides it. In your example nobody overrides the space formerly occupied by tmp, so you will typically see the value 17 survive intact in that memory.

但是,如果你这样做

int main(void) {
  volatile int *ptr;
  volatile int *ptrd;

  { // Block
    int tmp = 17;
    ptr = &tmp; // Just to see if the memory is cleared
  }

  { // Sibling block
    int d = 5;
    ptrd = &d;
  }

  printf("ptr = %d %d
", *ptr, *ptrd);
  printf("%p %p
", ptr, ptrd);
}

你会看到之前被 tmp 占用的空间已经被 d 重用,并且它之前的值被覆盖了.第二个 printf 通常会为两个指针输出相同的指针值.

you will see that the space formerly occupied by tmp has been reused for d and its former value has been overriden. The second printf will typically output the same pointer value for both pointers.

这篇关于当变量超出范围时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆