Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
408 views
in Technique[技术] by (71.8m points)

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...