Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 全局变量和链接问题_C++_Linker_Undefined Reference - Fatal编程技术网

C++ 全局变量和链接问题

C++ 全局变量和链接问题,c++,linker,undefined-reference,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文件中有这个定义(实际上是我的测试

我的库主要是基于头的,它使用了放置在库名称空间(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\u t是类型定义的)

但是,我希望在其他地方有这个定义,因此我创建了一个global.cpp文件,其中包含上述内容,并确保我的Makefile将其链接到其余文件。 有趣的是,在main.cpp和global.cpp中使用pten的定义进行编译可以很好地工作(我预计会出现双定义错误),但是在将定义保留在global.cpp中的同时删除main.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中)中使用extern关键字。

您在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
};
}
#包括
名称空间BigNum{
/**
*_uu_u为快速运行时查找预先存储了一些较低的十次方幂__
*/
extern const uintmax_t pten[];//这应该放在公共头文件中
康斯特马克私人有限公司[20]={
1LU、10LU、100LU、1000LU、10000LU、1000000LU、10000000LU、1000000000LU、10000000000LU、10000000000LU、10000000000LU、10000000000LU、10000000000LU、10000000000LU、10000000000LU、10000000000LU、10000000000000000LU、10000000000000000LU
};
}

检查:通常情况下,您会将
extern const uintmax_t pten[]在单独的公共头文件中。

链接错误?你告诉我们的不多,但如果你告诉我们的是准确的,我无法重现这个错误,也无法理解它。如果你给我们一个最简单完整的例子,我们也许可以把它弄清楚。我的心灵感应调试能力告诉我,你没有在BigNum名称空间中添加extern的头声明???@Beta示例。谢谢你调查,这是不可能的。不要混淆声明和定义。使用
时,extern
始终是一种声明。在哪里定义变量?请阅读:“与函数不同,所有全局变量都是静态的,因此在其他编译单元中是不可见的”——这句话是错误的。@ThorX89只添加
extern
的代码有点偶然,基本上是因为您正在初始化/分配变量的内存。@您是对的。我修好了。不是静态的。在多个编译单元中定义具有相同名称的全局变量会产生多个定义错误,因此从技术上讲,它们不是静态的,但在其他编译单元中看起来是不可见的。单位,除非用extern定义,除非它能工作,而且是由标准定义的,否则它不是不可能的。查看第40页,您将在其中找到
外部定义。谢谢它的工作方式有两种:在定义中使用一个extern,在main.cpp中使用一个extern声明,或者在两个文件中使用一个非extern定义和一个extern定义。我确实有一个带有pten外部声明的共享头,但我没有将其包含在global.cpp中。如果我有,那就解决了问题
  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
#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
};
}