如何在变量被绕过时使用变量?
在我看来,定义总是意味着存储分配。
在下面的代码中, int i
在程序堆栈上分配一个4字节(通常)存储并将其绑定到i
,并且i = 3
将该存储分配给3。 但由于goto
,定义被绕过,这意味着没有为i
分配存储空间。
我听说局部变量被分配在函数的入口f()
在这种情况下是f()
),或者在定义点。
但无论哪种方式,如何i
可以当它尚未(无存储所有)定义的使用呢? 执行i = 3
时分配给值3的值在哪里?
void f()
{
goto label;
int i;
label:
i = 3;
cout << i << endl; //prints 3 successfully
}
长话短说; goto
会导致运行时跳转,变量定义/声明会导致存储分配,编译时间。
编译器会看到,并决定多少存储空间分配为int
,也会使使该分配的存储空间将被设置为3
时,“打黑” i = 3;
。
即使在函数的开头有一个goto
,在声明/定义之前,那个内存位置也会在那里,就像你的例子一样。
非常愚蠢的比喻
如果我在地上放置一个日志,并且我的朋友(闭着眼睛)跑过去并跳过它,日志仍然会在那里 - 即使他没有看到或感觉到它。
如果他愿意,他可以转身(稍后)并放火烧掉,这很现实。 他的跳跃不会使日志神奇消失。
你的代码很好。 只要goto
不在那里,这个变量就会生活在哪里。
请注意,有些情况下您无法跳过声明:
C ++ 11 6.7声明语句[stmt.dcl]
3可以将其转换为块,但不能绕过具有初始化的声明。 从具有自动存储持续时间的变量不在范围内的点跳转到其在范围内的点的程序不合格,除非该变量具有标量类型,具有简单的默认构造函数和简单的析构函数的类类型,这些类型之一的cv限定版本,或前面类型之一的数组,并声明不带初始值设定项(8.5)。 [例如:
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
语句并没有绕过这个定义。
如果您使用带有构造函数的类而不是int
,则构造函数的调用将被goto
绕过,但存储将被分配。 然而,类实例将保持未初始化,所以在它的定义/初始化行获取控件之前使用它是一个错误。
上一篇: How can a variable be used when its definition is bypassed?
下一篇: Free variables that are declared inside switch statement blocks