是否保证在定义变量时确切地调用构造函数?

yep*_*ons 2 c++ standards constructor undefined-behavior c++11

请考虑以下代码:

#include <cstdio>

struct A {
  A() {
    printf("Bar\n");
  }
};

int main() {
  printf("Foo\n");
  A a;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

是否保证Foo\nBar\n按顺序打印?我的经验说"是",但是我想从C++ 11标准或MSDN引用中引用一些引用,因为有人告诉我编译器可能在实际的声明行之前调用构造函数.

如果构造函数有一些参数(因为它们可以依赖于函数启动时未计算的值),那将更加明显,如果只有默认构造函数则不太明显.比方说,JavaScript以在var可用行之前定义变量而闻名:

function main() {
  console.log(x);
  var x = 2;
  console.log(y);
}
main();
Run Code Online (Sandbox Code Playgroud)

上面的代码将打印undefined为值,x然后失败y is not defined.

Igo*_*nik 7

[intro.execution]/10全表达为不是另一种表达的子表达式的表达式.[ 注意:在某些情况下,例如未评估的操作数,语法子表达式被视为完整表达式(第5条).-end note ]如果定义了一个语言结构来产生函数的隐式调用,则语言结构的使用被认为是用于该定义目的的表达式.

.

[intro.execution]/14在与要评估的下一个完整表达式相关联的每个值计算和副作用之前,对与完整表达式相关联的每个值计算和副作用进行排序.


R S*_*ahu 6

因为有人告诉我,编译器可以在实际的声明行之前调用构造函数.

只有当它能够证明程序的可观察行为不会因此而改变时,编译器才能自由地这样做.在你的情况下,这是不正确的.因此,符合标准的编译器不会在声明行之前调用构造函数.


小智 5

您可以保证此程序将输出Foo\nBar\n.

但是,这就是你所保证的.这是您的程序将显示的行为,但通过as-if规则,您无法保证如何完成该行为.你不知道当构造函数被调用,甚至保证如果构造函数被调用.您的程序的可执行代码甚至可能根本没有构造函数!你甚至不能保证变量a存在于程序的某个地方.

这不是理论上的; 如果你的编译器是值得任何东西,以优化开启你的程序编译成完全相同同样的事情做节目

#include <cstdio>
int main() {
    std::printf("Foo\n");
    std::printf("Bar\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)