我有一个合成的例子,有我想改变的行为,但不太了解。
我拥有的是:
具有某些变量外部声明的公共标题 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;
}
可执行 supertest ,从源文件 main.cpp 编译并链接到两个库,静态和共享。这是源代码:
#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(Red Hat 4.4.7-4)(GCC)
在我有不同编译器的其他机器上: gcc版本4.6.4(Ubuntu / Linaro 4.6.4-1ubuntu1~12.04) 一切正常。
提前致谢!
答案 0 :(得分:2)
这是预期的行为。要解决这个问题,您可以将变量定义为弱,例如
#include "statich.h"
__attribute__((weak)) S nakedS;