c ++中的存储分配

Fih*_*hop 7 c++ initialization switch-statement

我正在阅读c ++第6章初始化和清理.作者说:

实际上,编译器更可能遵循C中的做法,即在该范围的左括号中为作用域分配所有存储.这无关紧要,因为作为程序员,在定义存储之前,您无法访问存储.尽管存储是在块的开头分配的,但构造函数调用直到定义对象的序列点才会发生,因为在此之前标识符不可用.编译器甚至会检查以确保您不将对象定义放在序列点仅有条件地通过它的位置,例如在switch语句中或goto可以跳过它的某个地方.

然后作者给出了一个例子如下:

class X {
public:
  X();
};

X::X() {}

void f(int i) {
  if(i < 10) {
   //! goto jump1; // Error: goto bypasses init
  }
  X x1;  // Constructor called here
 jump1:
  switch(i) {
    case 1 :
      X x2;  // Constructor called here
      break;
  // case 2 : // Error: case bypasses init
      X x3;  // Constructor called here
      break;
  }
} 

int main() {
  f(9);
  f(11);
}///:~
Run Code Online (Sandbox Code Playgroud)

我不明白为什么上面的代码没问题?根据我的理解,x2如果i不是可以绕过初始化1.

补充:

这句话"它实际上更可能是编译器将遵循C中的做法,即在该范围的左大括号中为作用域分配所有存储." 也困惑了我.

根据作者的描述,在开头括号中switch,编译器已经为x2和分配了空间x3.如果是这种情况,则有机会x2未初始化(案例1不满足).

Jon*_*ely 5

根据我的理解,如果i不是1,则可以绕过初始化x2.

不,既case 1可以执行,也x2可以在switch块结束时定义然后销毁,或者不执行任何情况,整个switch块都不执行任何操作,因此x2不在范围内,因此不会初始化但不能也指.因此它既存在又可以安全使用,或者它不存在.


seh*_*ehe 2

C++ 对象初始化和销毁​​语义是完全跳转安全的(包括异常、 goto 、 switch 和循环结构)。

\n

(唯一值得注意的例外是继承自 C 标准库 (setjmp/longjmp))

\n
\n

6.6 跳转语句

\n

2退出作用域时(无论已完成),在该作用域中构造的具有自动存储持续时间(3.7.3)的对象将以其构造的相反顺序被销毁。[注:对于临时变量,请参见 12.2。\xe2\x80\x94end note ]转出循环、转出块或返回具有自动存储持续时间的已初始化变量涉及销毁具有自动存储持续时间的对象,这些对象在传输点范围内但不在传输点范围内点转移到. (有关转移到块的信息,请参阅 6.7)。[ 注意:但是,可以终止程序(例如,通过调用 std::exit() 或 std::abort() (18.5)),而无需销毁具有自动存储持续时间的类对象。\xe2\x80\x94结束注]

\n
\n