6

可能重复:
我可以使用块来管理 C++ 中的变量范围吗?

我遇到了一些类似的 C++ 代码:

int main(void) {

  int foo;
  float qux;
  /* do some stuff */

  {
    int bar;
    bar = foo * foo;
    qux = some_func(bar);
  }

  /* continue doing some more stuff */
}

最初我认为也许原作者使用大括号对一些相关变量进行分组,但是由于设计中的系统没有足够的内存,我认为作者可能有意图解析bar 的范围和任何变量in 离开而不是让它们在整个封闭(foo 的)范围内。

有什么理由这样做吗?在我看来,这不应该是必要的,并且任何现代编译器都使这变得不必要?

4

6 回答 6

10

在我看来,这不应该是必要的,并且任何现代编译器都使这变得不必要?

是的,现代编译器会在这种情况下优化内存使用。额外的范围不会使代码更快或更高效。

但是,它们不能使用具有副作用的析构函数来优化对象,因为这会改变程序的行为。因此,对此类对象执行此操作是有意义的。

有什么理由这样做吗?

将相关代码组合在一起很有用。您知道在大括号内声明的变量不会在其他任何地方使用,这对了解非常有帮助。

于 2012-11-03T03:22:43.747 回答
4

如果您在一个方法中多次执行此操作,则可能会导致该方法占用更少的堆栈空间,具体取决于您的编译器。如果您资源有限,您可能使用的是微控制器,并且它们的编译器并不总是像 x86 编译器那样功能齐全。

此外,如果您使用完整的类(而不是整数和浮点数)来执行此操作,它可以让您控制调用析构函数的位置。

class MyClass;

int main(void) {

    int foo;
    float qux;
    /* do some stuff */

    {
        MyClass bar;
        qux = some_func(bar);
    } // <-- ~MyClass() called here.

    /* continue doing some more stuff */
}
于 2012-11-03T03:23:08.243 回答
4

在 C/C++ 的情况下,可以尝试限制名称之间的冲突(具有如此长的函数需要一个以这种方式限定变量范围是坏主意......)即,如果bar同一函数中有多个而不是以这种方式限定它们会让一个人确保它们不会相互碰撞/覆盖。

通常,函数内部的作用域不会影响堆栈分配大小 - 堆栈是为所有局部变量预先分配的,而与作用域无关。

于 2012-11-03T03:24:27.320 回答
3

如果代码真的像你展示的那样,那可能毫无意义。我见过的大多数编译器在进入函数时为所有局部变量分配空间,并在退出函数时释放它。不过还有一些其他的可能性。

如果您显示的bar是某个类类型的对象(尤其是带有析构函数的对象),则析构函数将在退出范围时运行,即使空间直到稍后才释放。

另一种可能性是实际上有两个内部作用域:

int main() { 
// ...

    { 
        // some variables
    }

// ...

    {
        // other variables
    }
}

在这种情况下,局部变量的空间将在进入 --but 时分配main并且some variables通常other variables)将共享相同的空间。即,分配的空间将足以容纳两者中的较大者,但不会(通常)是两者的总和,如果您在main's 范围内定义了所有变量,您将使用它。

于 2012-11-03T03:22:52.300 回答
2

打算让 bar 的范围解析和任何带有 in 的变量消失,而不是让它们在整个封闭(foo 的)范围内

这可能是一个(不重要和遗留)原因。
另一个原因是将它传达给int bar仅在此范围内使用的读者,以具有非常小的功能(函数内部的一种功能)。之后就没有用了bar

您的代码相当于:

  inline void Update (int &foo, float &qux)
  {
    int bar = foo * foo;
    qux = some_func(bar);
  }
  int main ()
  {
    ...
    Update(foo, qux);
    ...
  }

大多数编译器会优化对Update()内部的调用main()并将其内联,这会生成类似于您发布的内容。

于 2012-11-03T03:24:13.540 回答
2

它可能是为了帮助程序员,而不是优化输出,因为现代编译器肯定足够聪明,可以看到临时变量只使用一次。

另一方面,对于程序员来说,它增加了一个逻辑分离,它意味着“这些变量只需要这个代码”,也可能是“这个代码不会影响这个函数中的其他代码”。

于 2012-11-03T03:24:35.273 回答