2

我有一个小综合示例,它有我想改变的行为,但不太知道如何改变。

我所拥有的是:

  1. 具有某些变量的外部声明的公共头文件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;
    
  2. 从源文件 statich.cpp 编译的静态libstatic.a具有该外部变量的定义:

    #include "statich.h"
    
    S nakedS;
    
  3. 动态库libdyn.so从源文件dyn.cpp编译并与libstatic.a链接。这是源代码:

    #include "statich.h"
    
    void foo() {
      std::cout << "I'm foo() from dyn! nakedS.x == " << nakedS.x << std::endl;
    }
    
  4. 从源文件 main.cpp 编译与静态库和共享库链接的可执行超测试。这是源代码:

    #include "statich.h"
    int main() {
      std::cout << "nakedS.x == " << nakedS.x << std::endl;
    }
    
  5. 我有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 version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)

在我有不同编译器的其他机器上:gcc 版本 4.6.4 (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04) 一切正常。

提前致谢!

4

1 回答 1

2

这是预期的行为。要解决它,您可以将变量定义为弱,例如

#include "statich.h"

__attribute__((weak)) S nakedS;
于 2014-08-27T14:18:10.000 回答