【问题标题】:Relocation error with gcc when using extern使用 extern 时 gcc 的重定位错误
【发布时间】:2016-06-26 11:16:23
【问题描述】:

我收到以下代码的重定位错误。请有人帮我解决这个问题。

A.hpp

namespace
{
class A
{
    public:
        A(const std::string&);
        //Few Get() methods
    private:
        //Some private stuff
};
    extern A objA;
}

A.cpp

#include<A.hpp>

const std::string str("FIXED STRING HERE");
A objA(str);

A::A(const std::string& Istring)
{
    //Some data processing here
}

ClientCode.cpp

#include<A.hpp>



// Want to access A::get() here using objA;
objA.Get();

我收到以下错误:

重定位R_X86_64_PC32 对未定义符号`(匿名命名空间)::str' 在制作共享对象时不能使用;使用 -fPIC 重新编译
最终链接失败:错误值
collect2: ld 返回 1 个退出状态

另外,请有人知道这个外部对象的内存是什么时候分配的。 我的主要目的是只拥有 A 类的单个对象,并在我包含 A.hpp 时在许多文件中使用它

【问题讨论】:

    标签: c++


    【解决方案1】:

    A.hpp

    namespace ABC
    {
        class A
        {
            public:
                A(const std::string&);
                //Few Get() methods
            private:
                //Some private stuff
        };
      extern A objA;
    }
    

    A.cpp

    #include<A.hpp>
    namespace ABC
    {
         const std::string str("FIXED STRING HERE");
          A objA(str);
    
          A::A(const std::string& Istring)
          {
             //Some data processing here
          }
    }
    

    客户端代码.cpp

    #include<A.hpp>
    // Want to access A::get() here using objA;
    ABC::objA.Get();
    

    【讨论】:

      【解决方案2】:

      使用externClientCode.cpp 中的strobjA 显式声明为从其他cpp 源文件编译的其他目标文件定义的待链接符号。

      #include<A.hpp>
      
      extern const std::string str;
      extern A objA;
      
      // Want to access A::get() here using objA;
      objA.Get();
      

      ============ 编辑

      同时删除A.hpp中的extern语句

      namespace
      {
      class A
      {
          public:
              A(const std::string&);
              //Few Get() methods
          private:
              //Some private stuff
      };
          //extern A objA;
      }
      

      【讨论】:

      • 你的意思是我让 A.cpp 中的代码保持原样? const std::string str("这里的固定字符串");一个 objA(str);
      • @user3836455 是的。全局类初始化将在 main() 条目执行之前进行。
      • 抱歉,它不起作用。错误返回“错误:对'objA'的引用不明确”
      • @user3836455 objA.Get(); 应该在一个非全局函数中。
      • 是的,它不是全局的,它在函数内部
      【解决方案3】:

      重定位错误可能是由于“匿名”命名空间造成的。您必须为命名空间分配一个名称。

      至于何时为外部对象标识符分配内存,是在调用对象构造函数时。将对象标识符声明为外部具有向编译器指示标识符可以在多个文件中使用的效果,因此在链接时,包含该标识符的所有文件都指向同一个对象。

      显然,实例化(何时何地)取决于程序员,他们有责任正确地执行它以避免对象未实例化错误,一种空引用错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        • 2019-12-03
        • 1970-01-01
        • 2018-02-17
        • 2022-10-20
        • 2016-02-19
        相关资源
        最近更新 更多