Multiple definition error on variable that is declared and defined in header file and used only in its cpp file

送分小仙女□ 提交于 2021-02-02 03:41:00

问题


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.)


回答1:


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.




回答2:


The error goes away if I declare it as extern and define it in the cpp file,

The issue is that even when include guarded etc. the variable gets created once in each compilation unit - but since it is global it is pointing to same variable.

To overcome this is issue you need to either create it in anon. namespace

Something.h

namespace {
  int foo = 0;
}

Or, use the static keyword

Something.h

 static int foo = 0;

Both will create a different variable in each compilation unit.




回答3:


in C++ 17 you can resolve this issue by inline variables. Inline variables avoid the duplication of variables defined in header files. The variables defined in the header file will be treated as initialized in a cpp file. They won't be duplicated. So can be directly included the code.



来源:https://stackoverflow.com/questions/55238194/multiple-definition-error-on-variable-that-is-declared-and-defined-in-header-fil

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!