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

后端 未结 6 1466
遇见更好的自我
遇见更好的自我 2021-01-20 09:43

head.h


#pragma once

namespace foo
{
    int bar;

    int funct1();
}

head.cpp

#include \"head.h\"

int foo::funct1()
{
         


        
相关标签:
6条回答
  • 2021-01-20 10:01

    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;
    
    0 讨论(0)
  • 2021-01-20 10:04

    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.

    0 讨论(0)
  • 2021-01-20 10:10

    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;
    }
    
    0 讨论(0)
  • 2021-01-20 10:16

    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.

    0 讨论(0)
  • 2021-01-20 10:21

    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…

    0 讨论(0)
  • 2021-01-20 10:21

    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.

    0 讨论(0)
提交回复
热议问题