订单输入文件如何影响GCC中的链接和静态初始化?

fdl*_*dlm 5 c++ linker static gcc

假设我有以下文件:

LIB /阿

#ifndef A_H
#define A_H

#include <vector>

class A {
        public:
                static int add( int x );
                static int size();
        private:
                static std::vector<int> vec;
};

#endif
Run Code Online (Sandbox Code Playgroud)

LIB/A.cpp

#include "A.h"

std::vector<int> A::vec;

int A::add( int x ) {
        vec.push_back( x );
        return vec.size();
}

int A::size() { 
        return vec.size();
}
Run Code Online (Sandbox Code Playgroud)

LIB/BH1

#ifndef B_H
#define B_H

class B {
        public:
                static const int val = 42;
};

#endif
Run Code Online (Sandbox Code Playgroud)

LIB/B.cpp

#include "B.h"
#include "A.h"

int tempvar = A::add( B::val );
Run Code Online (Sandbox Code Playgroud)

最后:主要:cpp

#include <iostream>
#include "lib/A.h"
#include "lib/B.h"

int main() {
        std::cout << A::size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

此代码的结果因编译方式而异:

g++ main.cpp lib/A.cpp lib/B.cpp -o nolibAB
./nolibAB
Run Code Online (Sandbox Code Playgroud)

打印"1"

g++ main.cpp lib/B.cpp lib/A.cpp -o nolibBA
./nolibBA
Run Code Online (Sandbox Code Playgroud)

打印"0"

g++ -c lib/A.cpp lib/B.cpp
ar rvs lib.a A.o B.o
g++ main.cpp lib.a
./a.out
Run Code Online (Sandbox Code Playgroud)

打印"0"(无论我是否重新排序A.cpp和B.cpp)

有人能告诉我这种情况的原因吗?

编辑:我使用gcc 4.6.1

Joh*_*ski 1

标准未定义这一点。简而言之:您不应该依赖按特定顺序初始化的全局变量。

相关:C++ 中的静态初始化顺序问题

  • 不完全正确——单个编译单元中定义的全局变量将按照定义的顺序进行初始化。该顺序仅在编译单元之间未定义,这是OP的示例情况。因此,一种解决方法是将所有全局变量收集到一个编译单元中,并以受控顺序初始化它们。 (2认同)