Variable already defined in .obj; What is going on here?

核能气质少年 提交于 2019-12-02 00:08:05

The header head.h is included in two compilation units head.cpp and main.cpp. So the variable bar is defined twice. You could declare the variable without its definition the following way

#pragma once

namespace foo
{
    extern int bar;

    int funct1();
}

and then define it in some cpp module.

This foo namespace-level bar declaration:

namespace foo
{
    int bar;
}

is actually a definition.

To make it a declaration, mark the bar as extern in head.h:

namespace foo
{
    extern int bar;
}

Then define it in head.cpp:

int foo::bar = 0;
Michael Chourdakis

head.h is included in both main.cpp and head.cpp. So the variable is defined twice.

Possible Solution: make it inline. The "extern" solutions are also good, although older in approach.

namespace foo
{
    inline int bar;
}

How is it being defined multiple times?

It is defined once in head.cpp and once in main.cpp. That is a total of two times. This violates the one definition rule, which states that there may only be one definition for every variable.

int bar;

This is a definition of a variable. You've included it into two translation units.

A variable can be declared without definition in an extern declaration:

extern int bar;

Replace the definition with such declaration, and put the definition into exactly one translation unit.

I am not redefining anything. I am literally just assigning 1 to the variable

You're redefining the variable!

head.cpp has one via #include "head.h", and main.cpp has one via #include "head.h".

You need to merely declare it (unusual but not too strange) in the header:

extern int bar;

…then define it in one translation unit. This is just like what you do with static class members (albeit with slightly different syntax).

Since C++17, you may do this by instead plopping the inline keyword on to your definition.

Alternatively, avoid mutable globals…

Do carefully note that foo is not a class, but a namespace. When you declare a free variable in the header file:

int bar;

And then #include this header file multiple times (into different CPP files, causing multiple translation unit compilations), you'd get a linker error. Everyone knows it.

And, you'd add extern attribute at the declaration, and define the variable elsewhere in one of the CPP/C file.

Putting a global variable into a namespace is nothing but giving the global variable a different name. Think if foo::bar as foo__NS__bar, and hence you must add extern in the header and define foo::bar at some locatoin.

Note that this is different from a non-static member variable of a class. A class variable doesn't need to be defined/declared this way since the class is a type. Each instantiated variable of class-type would have a separate copy of the variable. Further to that, when you add a static variable in the class, you are giving that logically global variable another name. Thence, you must have that static-variable defined one of the CPP file.

The problem is you are defining foo::bar more than once: in header.h and in main.cpp. It's a global variable that's being defined more than once, and that's not possible. So the linker complains that you are defining it multiple times.

You can fix this by declaring foo::bar with extern:

namespace foo
{
    extern int bar;

    int funct1();
}

Then define it in header.cpp:

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