我有一个小综合示例,其中有我想要更改的行为,但不太知道如何更改。
我拥有的是这样的:
公共(public) header statich.h,具有某些变量的外部声明:
#include <iostream> struct S { S() : x(42) { std::cout << "S(), this=" << this << std::endl; } ~S() { std::cout << "~S(), this=" << this << std::endl; } int x; }; extern S nakedS;
从源文件statich.cpp编译的静态库libstatic.a,具有该外部变量的定义:
#include "statich.h" S nakedS;
动态库libdyn.so从源文件dyn.cpp编译并与libstatic.a链接。源代码如下:
#include "statich.h" void foo() { std::cout << "I'm foo() from dyn! nakedS.x == " << nakedS.x << std::endl; }
从源文件main.cpp编译并与静态和共享库链接的可执行supertest。源代码如下:
#include "statich.h" int main() { std::cout << "nakedS.x == " << nakedS.x << std::endl; }
我有 CMakeLists.txt 文件,可以为我构建所有这些内容。这是:
cmake_minimum_required(VERSION 2.8.12) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) add_library( static STATIC "statich.cpp" ) add_library( dyn SHARED "dyn.cpp" ) target_link_libraries( dyn static ) add_executable( supertest main.cpp ) set(DEPS static dyn ) target_link_libraries( supertest ${DEPS} )
重点是,当我运行 cmake 时。 && make && ./supertest
我得到了这个输出:
S(), this=0x6012c4
S(), this=0x6012c4
nakedS.x == 42
~S(), this=0x6012c4
~S(), this=0x6012c4
这意味着同一个对象的双重初始化,这根本不是我想要的。我可以改变这种行为而不用静态模拟替换 libdyn.so 吗?也许,一些编译器/链接器标志?我应该阅读什么才能了解更多信息?任何帮助将不胜感激。
此外,我在特定的编译器版本上遇到了此行为: gcc版本4.4.7 20120313(红帽4.4.7-4)(GCC)
在我有不同编译器的其他机器上: gcc版本4.6.4 (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04) 一切正常。
提前致谢!
最佳答案
这是预期的行为。要解决这个问题,您可以将变量定义为弱变量,例如
#include "statich.h"
__attribute__((weak)) S nakedS;
关于c++ - 外部链接变量多次初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25529450/