c++ - 在头文件中声明和定义且仅在其 cpp 文件中使用的变量的多重定义错误

标签 c++ linker extern

我正在将为一个芯片编译的代码移动到另一个芯片上。

出现的一个问题是大量的多重定义错误。其中一些似乎是由于第一个芯片的链接器让我懒得在多个源文件中使用变量 extern 时声明变量。我以前根本没有使用 extern(在 something.h 中声明和定义一个变量,在 something.cpp 和其他包含 something.h 的源文件中使用它)并且它编译和链接非常好。

我已经很好地解决了这些问题,我相信:现在我共享的变量具有这种模式:

某事.h

extern int foo;

某事.cpp

int foo = 0;

//using foo to do stuff

main.cpp

#include "Something.h"

//using foo to do stuff

一切顺利。

这是我不明白的地方,似乎无法在这里或在 Google 上找到任何答案。我注意到相同的多重定义错误是由在 Something.h 中声明和定义并在 Something.cpp 中使用的变量引起的。

Something.h 有一个包含保护,所以我不认为这是因为 Something.h 在我的程序中的某个地方被多次包含。

如果我将它声明为 extern 并在 cpp 文件中定义它,错误就会消失,但这对我来说是错误的。我相信不需要 extern 来链接 Something.h 和 Something.cpp 之间的变量。

任何建议将不胜感激,我真的很想了解我在这里遗漏了什么。

(顺便说一句,我正在使用 Arduino IDE 为 ESP32 编译。)

最佳答案

如果您在头文件中声明您的变量:

#ifndef GLOBAL_H
#define GLOBAL_H

int foo = 0;

#endif

在头文件或翻译单元的每个包含中,都会创建一个新的整数实例。正如你提到的,为了避免这种情况,你需要在头文件中将项目声明为“extern”,并在实现文件中对其进行初始化:

// .h
extern int foo;

// .cpp
int foo = 0

更多的 C++ 方法可以是这样的:

#ifndef GLOBAL_H
#define GLOBAL_H

struct Global {
    static int foo;
};
#endif

在你的 cpp 文件中:

#include "variables.h"

int Global::foo = 0;

C++17 用内联变量修复了这个问题,所以你可以这样做:

#ifndef GLOBAL_H
#define GLOBAL_H

inline int foo = 0;

#endif

参见 How do inline variables work?获取更多信息。

关于c++ - 在头文件中声明和定义且仅在其 cpp 文件中使用的变量的多重定义错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55238194/

相关文章:

c++ - 为什么在函数内初始化外部变量会出错?

c++ - 阻止模板类的所有实例化——包括支持的类型

c++ - UDP 客户端不在 esp32 上广播消息

haskell - GHC 可以将二进制文件链接到 libc 实现,例如 uclibc(默认在 OpenWrt 中使用)吗?

c++ - 如何一次运行多个运算符<<

ios - 在现有 iPhone 项目和 Watch Kit 扩展之间共享类

php - 构建 libphp5.so 以嵌入 C/C++

c++ - 外部变量的内存将存储在哪个文件中

c++ - 隐式转换为显式 bool 类型以对容器进行排序?

c++ - 如何解决多线程代码中for循环的依赖关系?