在头文件中声明和定义且仅在其cpp文件中使用的变量的多定义错误 [英] Multiple definition error on variable that is declared and defined in header file and used only in its cpp file

查看:63
本文介绍了在头文件中声明和定义且仅在其cpp文件中使用的变量的多定义错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

Something.h

  extern int foo; 

Something.cpp

  int foo = 0;//使用foo做事情 

Main.cpp

  #include"Something.h"//使用foo做事情 

一切都很好.

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

Something.h有一个include防护,所以我不认为这是由于Something.h在程序的某个位置多次被包含.

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

任何建议将不胜感激,我真的很想了解我在这里缺少的内容.

(顺便说一下,我正在使用Arduino IDE编译ESP32.)

解决方案

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

  #ifndef GLOBAL_H#定义GLOBAL_Hint foo = 0;#万一 

在头文件或转换单元的每个包含中,都会创建整数的新实例.如前所述,为避免这种情况,您需要在头文件中将该项目声明为"extern",并在实现文件中对其进行初始化:

 //.hextern int foo;//.cppint foo = 0 

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

  #ifndef GLOBAL_H#定义GLOBAL_Hstruct Global {静态int foo;};#万一 

在您的cpp文件中:

  #include"variables.h"int Global :: foo = 0; 

C ++ 17使用内联变量解决了此问题,因此您可以执行以下操作:

  #ifndef GLOBAL_H#定义GLOBAL_H内联int foo = 0;#万一 

有关更多信息,请参见内联变量如何工作?.

I'm in the process of moving code written to be compiled for one chip onto another chip.

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:

Something.h

extern int foo;

Something.cpp

int foo = 0;

//using foo to do stuff

Main.cpp

#include "Something.h"

//using foo to do stuff

All good.

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 has an include guard, so I don't think it's due to Something.h being included multiple times somewhere in my program.

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.

(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

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

A more C++ way to do that can be something like this:

#ifndef GLOBAL_H
#define GLOBAL_H

struct Global {
    static int foo;
};
#endif

And in your cpp file:

#include "variables.h"

int Global::foo = 0;

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.

这篇关于在头文件中声明和定义且仅在其cpp文件中使用的变量的多定义错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆