C++ 提交C/C+的原因+;未命名范围中的变量?
可能重复:C++ 提交C/C+的原因+;未命名范围中的变量?,c++,scope,scoping,low-memory,C++,Scope,Scoping,Low Memory,可能重复: 我遇到了一些类似于的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 */ } 起初我认为,也许最初的作者使用大括号对一些相关变量进行分组,但由于设计中的系统没有足够的内存,我认为
我遇到了一些类似于
的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的)范围
有什么理由这样做吗?在我看来,这是不必要的,任何现代编译器都不需要这样做
在我看来,这不应该是必要的,任何现代编译器都不需要这样做
是的,现代编译器会在这种情况下优化内存使用。额外的作用域不会使代码更快或更高效
但是,他们不能用具有副作用的析构函数优化对象,因为这会改变程序的行为。因此,这对此类对象是有意义的
有什么理由这样做吗
将相关代码组合在一起是很有用的。你知道大括号内声明的变量不会在其他任何地方使用,这一点非常有帮助。如果代码真的像你所展示的那样,那么它可能几乎毫无意义。我所见过的大多数编译器都会在函数入口为所有局部变量分配空间,然后在退出函数时使用ase。不过还有一些其他的可能性 如果显示为
bar
的对象是某个类类型的对象(特别是带有析构函数的对象),则析构函数将在退出作用域时运行,即使直到稍后才释放空间
另一种可能性是,实际上有两个内部作用域:
int main() {
// ...
{
// some variables
}
// ...
{
// other variables
}
}
在这种情况下,局部变量的空间将在输入时分配到
main
——但是,一些变量和其他变量将(通常)共享相同的空间。即,分配的空间将足以容纳两个变量中较大的一个,但不会(通常)如果在main
的作用域中定义所有变量,则使用这两个变量的总和。如果在一个方法中多次这样做,则可能导致该方法占用更少的堆栈空间,具体取决于编译器。如果资源有限,则可能使用微控制器,并且它们的编译器并不总是那么满-以x86编译器为特色
此外,如果使用完整类(而不是int&float)执行此操作,则可以控制调用析构函数的位置
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 */
}
class-MyClass;
内部主(空){
int foo;
浮点数;
/*做点什么*/
{
MyClass酒吧;
qux=某些函数(bar);
} //
具有bar范围解析的意图,以及具有in go的任何变量
而不是让他们在整个封闭空间内(foo's)
范围
这可能是一个(不重要和遗留)原因。
另一个原因是要向读者传达,int bar
仅在这个范围内使用,以获得非常小的功能(函数内部的函数)。此后,就不再使用bar
您的代码相当于:
inline void Update (int &foo, float &qux)
{
int bar = foo * foo;
qux = some_func(bar);
}
int main ()
{
...
Update(foo, qux);
...
}
大多数编译器都会在main()
内部优化对Update()
的调用,并将其内联,从而生成类似于您发布的内容。对于C/C++来说,可以尝试限制名称之间的冲突(函数太长,需要一个变量以这种方式作用域是不好的主意…)也就是说,如果在同一个函数中有多个条
,那么通过这种方式确定它们的范围将确保它们不会相互碰撞/覆盖
通常情况下,函数内部的作用域不会影响堆栈分配大小-堆栈是为所有局部变量预先分配的,而与作用域无关。这可能是为了帮助程序员,而不是优化输出,因为现代编译器当然足够聪明,可以看到临时变量只使用一次
另一方面,对于程序员来说,它添加了一个逻辑分隔,这意味着“这些变量仅用于此代码”,并且可能“此代码不会影响此函数中的其他代码”即使编译器可以优化内容,尽可能地限制范围也是一种好的做法。例如,允许您以后再次使用相同的变量名。对于i
s、j
s和x
s非常有用。@Thilo:如果您反复使用内容,则需要将函数拆分!另外,for(int i;…)
已经有了作用域i
。谢谢大家的回答!@Peter O.,Kate Gregory:这不是重复的。问题特别是关于内存消耗(对象生存期)。这里没有合适的地方来添加未命名作用域的其他原因。