const extern C-array链接器的多个定义

时间:2013-03-03 07:04:53

标签: c++

我有几个源文件可以更新它们。他们拒绝编译的原因很明显(所有无趣的消息来源都被删除):

// hashset.h
class HashSet {
    unsigned prime = 0; // Index to table size (c++11 syntax)
    unsigned long table_size () const { return prime_list [prime]; }
};

//hashet.cpp
const unsigned long prime_list [] = {53, 97, 193, 389, 769,
      1543, 3079, 6151, 12289, 24593, 49157, 98317};
从标题中的prime_list调用时,

HashSet::table_size未定义。我尝试修复源代码,将extern const unsigned long prime_list [];添加到标头并将extern添加到此数组定义中。在我make clean && make之后

g++ main.o dictionary.o hashset.o  -o spell
dictionary.o:(.rodata+0x4): multiple definition of `num_primes'
main.o:(.rodata+0x4): first defined here
dictionary.o:(.rodata+0x20): multiple definition of `prime_list'
main.o:(.rodata+0x20): first defined here
hashset.o:(.rodata+0x4): multiple definition of `num_primes'
main.o:(.rodata+0x4): first defined here
hashset.o:(.rodata+0x20): multiple definition of `prime_list'
main.o:(.rodata+0x20): first defined here
collect2: error: ld returned 1 exit status

正如我发现的那样,事实上只要将prime_table定义为

// hashset.cpp
extern const unsigned long prime_list [] = {53, 97, 193, 389, 769,
      1543, 3079, 6151, 12289, 24593, 49157, 98317};

并且table_size ()的主体移动到hashset.cpp(为了避免编译错误),我得到了这些链接器错误。没有extern我没有错误。为什么会这样?我只有这个数组的一个定义,我不会以任何方式将它暴露给其他我的源文件(我现在不把extern const unsigned long prime_list [];放到标题中)。它如何被多重定义?

要明确,我的来源现在:

// hashset.h
class HashSet {
    unsigned prime = 0; // Index to table size (c++11 syntax)
    unsigned long table_size () const;
};

//hashet.cpp
extern const unsigned long prime_list [] = {53, 97, 193, 389, 769,
      1543, 3079, 6151, 12289, 24593, 49157, 98317};
unsigned long HashSet::table_size () const {
     return prime_list [prime];
}

现在extern中的.cpp是不必要的,但我只是想知道,出了什么问题?有没有办法将table_size()的正文放回头文件以允许它内联?

upd prime_listprime_table是同一个对象。我错误地更改了名称,同时缩短了这篇文章的来源;现在修好了。

2 个答案:

答案 0 :(得分:0)

删除extern。应该没问题。

要将方法放入头文件,只需在头文件中使用extern声明数组。

 extern const unsigned long prime_table [];

此外,由于prime_table,您没有收到错误,但是num_primes。

完美适合我。

构建配置项目tmpCheck的调试**

全力以赴 构建文件:../ src / hashset.cpp 调用:GCC C ++编译器 g ++ -O0 -g3 -Wall -c -fmessage-length = 0 -MMD -MP -MF“src / hashset.d”-MT“src / hashset.d”-o“src / hashset.o”“../ SRC / hashset.cpp” 完成建筑:../ src / hashset.cpp

构建文件:../ src / tmpCheck.cpp 调用:GCC C ++编译器 g ++ -O0 -g3 -Wall -c -fmessage-length = 0 -MMD -MP -MF“src / tmpCheck.d”-MT“src / tmpCheck.d”-o“src / tmpCheck.o”“../ SRC / tmpCheck.cpp” 完成建筑:../ src / tmpCheck.cpp

构建目标:tmpCheck 调用:GCC C ++链接器 g ++ -o“tmpCheck”./ src / hashset.o。/ src / tmpCheck.o
完成建筑目标:tmpCheck

构建完成**

 #ifndef HASHSET_H_
 #define HASHSET_H_

  extern const unsigned long prime_list [];
  // hashset.h
  class HashSet {
     unsigned prime ; // Index to table size (c++11 syntax)
   public:
      HashSet():prime(0){
        //
      }
      unsigned long table_size () const { return prime_list [prime]; }

  };
  #endif /* HASHSET_H_ */

   #include "hashset.h"
   //hashet.cpp
   const unsigned long prime_list [] = {53, 97, 193, 389, 769,
      1543, 3079, 6151, 12289, 24593, 49157, 98317};

答案 1 :(得分:0)

我认为如果@Adnan Akbar建议使用extern特定器没有解决问题,那么可能是由于多次包含头文件引起的。
所以在这种情况下,你可以找到一个简单的解决方案:
使用条件翻译指令
#pragma在你的“hashset.h”中一次