C++中未在main作用域声明的eleven为何构造早于局部对象two
参考代码
#include <string> #include <iostream> using namespace std; class S { public: string name_; S(string const& name) : name_(name) { cout << "create " << name << endl; } ~S() { cout << "destroy " << name_ << endl; } }; S one("one"); int main() { S two("two"); //eleven.name_; error 'eleven' was not declared in this scope } S eleven("eleven");
问题1解答:为什么eleven的构造函数调用时机早于two的构造函数?
one和eleven都是全局非局部变量,C++标准明确规定:所有全局非局部变量的动态初始化,都会在main函数执行之前完成。- 同一个翻译单元(即当前.cpp文件)内的全局变量,会按照代码中定义的先后顺序完成初始化,因此先定义的
one先构造,后定义的eleven后构造,二者都在main启动前完成构造流程。 - 而
two是main函数内部的局部变量,只有进入main函数、执行到对应定义行时才会触发构造,因此eleven的构造时机早于two。
问题2解答:为什么在main函数内提示eleven未声明,但其构造函数却被调用了?
这是因为C++中编译期可见性和运行期执行逻辑是完全分离的两套规则:
- 编译阶段编译器会从上到下扫描代码,
eleven的定义写在main函数之后,在main内部引用eleven的位置,编译器还没有扫描到eleven的任何声明,因此会报“未声明”的编译错误,这属于编译期的语法检查规则。 - 而全局变量的构造执行是运行期的逻辑,由链接器在生成可执行文件时,把所有全局变量的构造逻辑注册到
main执行前的初始化流程中,不管变量定义在文件的哪个位置,只要是合法定义的全局变量都会被纳入这个初始化流程,和编译期某个位置能不能看到它的声明没有关联。
内容的提问来源于stack exchange,提问作者titanium
相关产品推荐
相关产品推荐

