在头文件中声明和定义且仅在其 cpp 文件中使用的变量的多重定义错误
我正在将编写为一个芯片编译的代码转移到另一个芯片上.
I'm in the process of moving code written to be compiled for one chip onto another chip.
出现的一个问题是多个定义错误.其中一些似乎是由于第一个芯片的链接器让我在跨多个源文件使用变量时懒得声明变量 extern.我以前根本没有使用 extern(在 something.h 中声明和定义一个变量,在 something.cpp 和包含 something.h 的其他源文件中使用它)并且它编译和链接得很好.
One issue that's come up is a multitude of multiple definition errors. Some of which appear to be due to the linker for the first chip letting me be lazy with declaring variables extern when they are to be used across multiple source files. I didn't use extern at all previously (declare and define a variable in something.h, use it in something.cpp and other source files that included something.h) and it compiled and linked perfectly well.
我相信我已经很好地解决了这些问题:现在我共享的变量具有这种模式:
I've fixed these issues well enough, I believe: now my variables that are shared have this pattern:
某事.h
extern int foo;
Something.cpp
Something.cpp
int foo = 0;
//using foo to do stuff
Main.cpp
#include "Something.h"
//using foo to do stuff
一切都好.
这是我不明白的部分,似乎无法在此处或在 Google 上找到任何答案.我注意到同样的多重定义错误是由在 Something.h 中声明和定义并在 Something.cpp 中仅使用的变量引起的.
Here's the bit I don't understand, and can't seem to find any answers to here or on Google. I've noticed the same multiple definition errors being caused by variables that are declared and defined in Something.h and used only in Something.cpp.
Something.h 有一个包含守卫,所以我不认为这是因为Something.h 在我的程序中被多次包含.
Something.h has an include guard, so I don't think it's due to Something.h being included multiple times somewhere in my program.
如果我将它声明为 extern 并在 cpp 文件中定义它,错误就会消失,但这对我来说感觉不对.我相信不需要外部变量来链接Something.h和Something.cpp之间的变量.
The error goes away if I declare it as extern and define it in the cpp file, but this feels wrong to me. I believe the extern is not needed to link a variable between a Something.h and Something.cpp.
任何建议将不胜感激,我真的很想了解我在这里缺少什么.
Any advice would be greatly appreciated, I'd really like to understand what I'm missing here.
(顺便说一下,我正在使用 Arduino IDE 为 ESP32 编译.)
(I'm compiling for ESP32 using the Arduino IDE by the way.)
推荐答案
如果你在头文件中声明你的变量:
If you declare your variable in the header file:
#ifndef GLOBAL_H
#define GLOBAL_H
int foo = 0;
#endif
在头文件或翻译单元的每个包含中,都会创建一个整数的新实例.如您所述,为避免这种情况,您需要在头文件中将该项目声明为extern"并在实现文件中对其进行初始化:
In every include of your header file or translation unit, a new instance of your integer is created. As you mentioned, to avoid this, you need to declare the item as "extern" in the header file and initialize it in the implementation file:
// .h
extern int foo;
// .cpp
int foo = 0
更多的 C++ 方式可以是这样的:
A more C++ way to do that can be something like this:
#ifndef GLOBAL_H
#define GLOBAL_H
struct Global {
static int foo;
};
#endif
在你的 cpp 文件中:
And in your cpp file:
#include "variables.h"
int Global::foo = 0;
C++17 用内联变量修复了这个问题,所以你可以这样做:
C++17 fixes this problem with inline variables, so you can do:
#ifndef GLOBAL_H
#define GLOBAL_H
inline int foo = 0;
#endif
有关详细信息,请参阅内联变量如何工作?.
See How do inline variables work? for more information.
相关文章