假设我有以下片段:
Foo foo;
....
return bar();
现在,C++标准是否保证bar()在foo::~Foo()之前被调用?还是由编译器/实现来决定?
谢谢!
假设我有以下片段:
Foo foo;
....
return bar();
现在,C++标准是否保证bar()在foo::~Foo()之前被调用?还是由编译器/实现来决定?
谢谢!
这是保证行为。实际执行的过程如下展开:
0: enter block (scope)
1: Foo::Foo()
2. evaluation of bar(); as expression in return statement
3. save result of the expression as value returned from function
4. finalize return statement to leave function to its caller (request exit from current scope)
5: exit block (scope) with call to Foo::~Foo()
以下是一些来自标准的参考文献:
1.9 程序执行
10 每个带有自动存储期的对象实例(3.7.2)都与进入其块相关联。
foo
具有自动存储期,并且:3.7.2 自动存储期
1 显示声明为自动或注册存储类,未显式声明为静态或外部链接的本地对象具有自动存储期。这些对象的存储持续到创建它们的块退出。
6.6.3 return 语句
2 (...)表达式的值被返回给函数的调用者
和
6.6 跳转语句 (return 属于跳转语句)
2 在离开作用域时(不管如何),对于具有自动存储期的所有构造对象(3.7.2),将调用析构函数(12.4)。
6.7 声明语句
2 在块中声明的具有自动存储期的变量在退出该块时被销毁。
和
12.4 析构函数
10 析构函数被隐式调用(1)对于具有静态存储期的构造对象(3.7.1)在程序终止(3.6.3)时,(2)对于具有自动存储期的构造对象(3.7.2)当创建对象的块退出(6.7)时。
从 C++ 标准的所有细节中抓住单个想法并不容易。希望快速概述将帮助您自己进行这种分析。
是的,在foo对象的析构函数被调用之前,bar()函数将被调用。
标准规定:
6.6:“无论如何脱离作用域,都会为该作用域中声明的所有具有自动存储期(3.7.2)(命名对象或临时对象)的构造对象调用析构函数(12.4),按照它们的声明顺序的反向顺序。”
直到return语句执行完毕,才离开作用域。
当离开作用域时,对象会被销毁。
return
离开作用域,但在执行 bar()
之前无法返回。因此,bar()
被调用。
想象一下,如果它是 return bar(foo);
?这只是必须工作的,如果销毁顺序取决于是否将其作为参数传递,那将是愚蠢的。