全局变量和链接问题

时间:2013-06-23 13:35:13

标签: c++ linker undefined-reference

我的主要是基于头的库使用放置在库命名空间(BigNum)中的全局变量。 变量的定义如下:

namespace BigNum{
/**
* __Some lower powers of ten prestored for fast runtime lookup.__*/
const uintmax_t pten[20]={
1LU, 10LU, 100LU, 1000LU, 10000LU, 100000LU, ....
};
}

只要我在main.cpp文件中有这个定义(我的测试配置中唯一的非头文件),并且我的标题中包含extern uintmax_t pten[];(前提是它们还包含cstdint,其中uintmax_t),一切正常是typedefined)。

但是,我希望在其他地方有这个定义,所以我创建了一个global.cpp文件,其中包含上述内容,并确保我的Makefile将其链接到其余文件。 有趣的是,在main.cpp和global.cpp中使用pten的定义进行编译工作正常(我希望双重定义错误),但是从main.cpp中删除定义而将其留在global.cpp会导致链接错误。

我检查了生成的global.o,它确实包含了pten符号(它的错位形式)。尝试以任一顺序手动链接main.o和global.o失败。

有什么想法吗?

其他信息: 这是一个阐述问题的基本例子。

的main.cpp

    #include <cstdint>
    #include <iostream>

    namespace BigNum{
    extern const uintmax_t pten[];
    }
    int main( int argc, const char *argv[] )
    {
        using namespace std;

        cout<<BigNum::pten[0]<<endl;
        return 0;
    }

global.cpp

    #include <cstdint>

    namespace BigNum{
    /**
     * __Some lower powers of ten prestored for fast runtime lookup.__
     */
    const uintmax_t pten[20]={
        1LU, 10LU, 100LU, 1000LU, 10000LU, 100000LU, 1000000LU, 10000000LU, 100000000LU, 1000000000LU, 10000000000LU, 100000000000LU, 1000000000000LU, 10000000000000LU, 100000000000000LU, 1000000000000000LU, 10000000000000000LU, 100000000000000000LU, 1000000000000000000LU, 10000000000000000000LU
    };
    }

汇编:

  g++ -std=c++0x -c global.cpp -o global.o
  g++ -std=c++0x -c main.cpp -o main.o
  g++ -std=c++0x global.o main.o

 >main.o: In function `main':
 >main.cpp:(.text+0x12): undefined reference to `BigNum::pten'
 >collect2: ld returned 1 exit status

2 个答案:

答案 0 :(得分:2)

您在global.cpp中的代码应为:

#include <cstdint>

namespace BigNum{
/**
 * __Some lower powers of ten prestored for fast runtime lookup.__
 */
extern const uintmax_t pten[]; //This should go in a common header file
const uintmax_t pten[20]={
    1LU, 10LU, 100LU, 1000LU, 10000LU, 100000LU, 1000000LU, 10000000LU, 100000000LU, 1000000000LU, 10000000000LU, 100000000000LU, 1000000000000LU, 10000000000000LU, 100000000000000LU, 1000000000000000LU, 10000000000000000LU, 100000000000000000LU, 1000000000000000000LU, 10000000000000000000LU
};
}

检查this guide:通常,您会将extern const uintmax_t pten[];放在单独的公共头文件中。

答案 1 :(得分:-1)

问题解决了。 与函数不同,所有全局变量都是其他编译单元不可见的。要使它们可见, extern 关键字也必须在其定义中使用(在global.cpp中)。