代码之家  ›  专栏  ›  技术社区  ›  Corey Ogburn

范围定义括号和堆栈?

  •  1
  • Corey Ogburn  · 技术社区  · 14 年前

    Why are different case condition bodies not in different scope?

    在这个问题中,OP谈到了他如何知道自己可以手动添加插件 {}

    4 回复  |  直到 7 年前
        1
  •  3
  •   Rob    14 年前

    它所做的只是定义另一个作用域,而不是将其转换为方法调用。记住,对于局部变量,CLR/JVM可以决定根本不使用堆栈空间,它可以选择使用处理器寄存器。在某些情况下,如果你原谅这个双关语,它可能会决定优化一些当地人,因为他们不被需要。它甚至可以决定,它可以使用一个寄存器,或内存位置“在堆栈上”的多个变量,因为他们永远不会重叠。

    以链接问题为例:

    switch(condition) {
      case CONDITION_ONE: {
        int account = 27373;
      }
      case CONDITION_TWO: {
        // account var not needed here
      }
      case CONDITION_THREE: {
        // account var not needed here
      }
      case CONDITION_FOUR: {
        int account = 90384;
      }
    }
    

    从目前的情况来看,该代码在功能上与:

    int account;
    
    switch(condition) {
      case CONDITION_ONE: {
        account = 27373;
      }
      case CONDITION_TWO: {
        // account var not needed here
      }
      case CONDITION_THREE: {
        // account var not needed here
      }
      case CONDITION_FOUR: {
        account = 90384;
      }
    }
    

    作为 account

        2
  •  2
  •   James Curran    14 年前

    范围由编译器在编译时定义。它对变量的实际内存布局几乎没有影响。因此,如果我要写:

    func()
    { 
        int a;
        {
          int b;
        }
        {
          int c;
        }
    }
    

        3
  •  1
  •   munificent    14 年前

    我的问题是,这是怎么回事?它是否会像一个方法调用一样上升到堆栈中?

    它的工作原理与用于创建新本地作用域的任何其他{}对一样。这两者在范围上没有区别:

    void foo() {
        {
            int a = 123;
        }
        // a is gone here
        {
            // different a
            float a = 12.3f;
        }
    }
    

    还有这个:

    void foo() {
        switch (123) {
        case 1:
            {
                int a = 123;
            }
            // a is gone here
            break;
    
        case 2:
            {
                // different a
                float a = 12.3f;
            }
        }
    }
    

    块始终可以访问其外部作用域,否则这将不起作用:

    void foo() {
        int a = 123;
        if (true) {
            a = 345; // accessing a in outer scope
        }
    }
    
        4
  •  0
  •   Frxstrem    14 年前

    {} 在许多编程语言中创建变量,当离开该作用域时,这些变量将被销毁。

    此外,使用时也会出现问题 switch

    int main() {
      int foo = 4;
      int bar = getbar(); // getbar() is a function returning an integer
      switch(bar)
      {
        case 1:
          int abc = 6;
          break;
        case 2:
          int abc = 7; // compiler error: 'abc' was defined twice in this scope
          break;
      }
    }
    int abc = 147; // This is no error, as 'abc' fell out of scope when
    // leaving the `switch` statement
    

    如你所见, abc 已在 转换 ,这将导致一个错误。这将很容易被固定为给予每一个 case 它自己的变量范围:

    int main() {
      int foo = 4;
      int bar = getbar(); // getbar() is a function returning an integer
      switch(bar)
      {
        case 1:
        {
          int abc = 6;
          break;
        }
        case 2:
        {
          int abc = 7; // no more errors, since these declarations will destruct when
          // falling out of scope
          break;
        }
      }
    }
    int abc = 147; // This is no error, as 'abc' fell out of scope when
    // leaving the `switch` statement