【发布时间】:2011-06-14 19:10:44
【问题描述】:
只是为了好玩,我正在研究静态对象的动态初始化顺序。 在文件名 t.h 中,我放了
struct T {
static std::vector<std::string> me;
static int add(std::string s) { me.push_back(s); return me.size(); }
};
(加上向量和字符串所需的标题。) “std::vector T::me”在 t.cpp 中。 文件 main.cpp 打印出 T::me: 中的值:
#include "t.h"
#include <iostream>
using namespace std;
int main()
{
T::me.push_back("main");
cout << "T::me.size()=" << T::me.size() << endl;
for (unsigned i = 0; i<T::me.size(); ++i) {
cout << i << "-" << T::me[i] << endl;
}
return 0;
}
接下来,我创建“a.cpp”并将以下内容放入其中:
#include "t.h"
int a = T::add("a");
根据需要使用“b”和“c”对文件 b.cpp 和 c.cpp 执行类似操作。 使用 g++ *.cpp 编译,然后运行 ./a.out。未指定从编译单元到编译单元的静态初始化顺序。就我而言,它始终按字母倒序排列。我得到: 3 - c 2 - b 1 - 一个 0 - 主要
目前没有问题。
现在我像 a.cpp 一样创建 u.cpp,但使用“u”。重新编译/重新运行,“u”没有出现在列表中。
是因为我从来没有引用过你吗?我从未引用过 a、b、c,但我更改了 main:
#include "t.h"
#include <iostream>
using namespace std;
extern int u;
int main()
{
cout << "u=" << u << endl;
T::me.push_back("main");
cout << "T::me.size()=" << T::me.size() << endl;
for (unsigned i = 0; i<T::me.size(); ++i) {
cout << i << "-" << T::me[i] << endl;
}
return 0;
}
程序打印出“u=2”,但“u”不在列表中。你不应该在使用之前被动态初始化,因此,T::me 已经更新为包含“u”吗?我认为应该有比字母表中 u 排在 t 之后更好的解释。
【问题讨论】:
-
需要我指出,试图找出官方未指明的行为的细节只是远离依赖这些细节的一步,我们作为一个社区不希望任何一个?
-
“只是为了好玩”是一个合理的借口。我愿意让 OP 怀疑他们不会发送任何依赖于这种行为的生产代码,无论它可能被发现是什么。但是按照这个逻辑,也许应该把它移到programmers.stackexchange.com
-
我不认为我的问题属于未指定行为的领域。如果我问“你什么时候初始化 w.r.t. a,b,c...”那将是未指定的。
标签: c++