Eri*_*c Z 36 c++ scope variable-declaration
在我看来,定义总是意味着存储分配.
在以下代码中,int i
在程序堆栈上分配一个4字节(通常)存储并将其绑定到i
,i = 3
并将3分配给该存储.但是因为goto
,定义被绕过,这意味着没有分配存储空间i
.
我听说局部变量在函数的入口处(f()
在这种情况下)分配在它们所在的位置,或者在定义点处.
但无论哪种方式,如何i
在尚未定义的情况下使用它(根本没有存储空间)?执行时分配给值3的位置在哪里i = 3
?
void f()
{
goto label;
int i;
label:
i = 3;
cout << i << endl; //prints 3 successfully
}
Run Code Online (Sandbox Code Playgroud)
Fil*_*efp 44
长话短说; goto
将导致运行时跳转,变量定义/声明将导致存储分配,编译时间.
编译器将查看并决定为a分配多少存储空间int
,它还可以使这个分配的存储空间3
在"命中"时设置为i = 3;
.
即使goto
在函数的开头有一个内存位置,在声明/定义之前,就像在你的例子中一样.
如果我在地上放置一根木头并且我的朋友跑了(闭着眼睛)并跳过它,那么原木仍然会在那里 - 即使他没有看到或感觉到它.
如果他愿意的话,可以说他可以转身(在以后的时间)并将其置于火上是很现实的.他的跳跃并没有让日志神奇地消失.
NPE*_*NPE 16
你的代码很好.变量生活在没有生存的地方goto
.
请注意,有些情况下您无法跳过声明:
C++ 11 6.7声明声明[stmt.dcl]
3可以转换为块,但不能以初始化方式绕过声明.从具有自动存储持续时间的变量不在范围内的点跳转到其在范围内的点的程序是不正确的,除非该变量具有标量类型,具有普通默认构造函数的类类型和普通的析构函数,这些类型之一的cv限定版本,或者前面类型之一的数组,并且在没有初始值设定项的情况下声明(8.5).[例如:
Run Code Online (Sandbox Code Playgroud)void f() { // ... goto lx; // ill-formed: jump into scope of `a' // ... ly: X a = 1; // ... lx: goto ly; // ok, jump implies destructor // call for `a' followed by construction // again immediately following label ly }
- 末端的例子]
定义不是可执行代码.它们只是编译器的指令,让它知道变量的大小和类型.从这个意义上讲,该定义并未被该goto
声明所绕过.
如果使用带有构造函数而不是a的类,则构造函数int
的调用将被旁路goto
,但无论如何都会分配存储.但是,类实例将保持未初始化状态,因此在定义/初始化行之前使用它会获得控件是一个错误.