creating global variables causes linker error

2019-01-19 18:43发布

问题:

I have an MFC application AVT_testapp, and in the header file (AVT_testappDlg.h) I am trying to create a variable outside of all functions, classes, etc. in order to make it global. Whenever I try to do this though (say I try int x = 7), I get the error:

1>AVT_testappDlg.obj : error LNK2005: "int x" (?x@@3HA) already defined in 
    AVT_testapp.obj
1>..\..\bin\x64\Debug\AVT_testapp.exe : fatal error LNK1169: one or more 
    multiply defined symbols found

Everything I have found on google says "just add header guards". AVT_testappDlg has 6 #include's, and each of them has header guards.

What else could be causing these errors when creating global variables?

EDIT: Here is the beginning of my header file,

#pragma once

#include "../../src/CoreUtils/nierr.h"
#include "..\..\src\CoreUtils\StringHelpers.h" //includes windows.h
#include "afxwin.h"
#include "afxcmn.h"
#include "IFrameObserver.h"
#include "c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\GdiPlusHeaders.h"
//#include <fstream>
//#include <windows.h>

int x = 7;

using namespace AVT::VmbAPI;


//////////////////////////////////////////////////////////////////////////
//////////  MyObserver class   ///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class MyObserver : public IFrameObserver
{
private:
    MyObserver( MyObserver& );

    MyObserver& operator=( const MyObserver& );    

public:

    VmbUchar_t* imageData;

            //...
            //...
            //...
            //...

//that's the end of the relevant stuff

回答1:

You cannot define variables at namespace level in a header. In general it is best not to have global variables, but if you need to you should provide only a declaration in the header and the definition in a single .cpp:

//header
extern int i;

//cpp
int i;

The problem with your code is not related to header guards. Header guards ensure that a header is parsed only once in each translation unit. Lack of header guards causes compiler errors, where the compiler sees, say for example a class, defined multiple times in the same translation unit after preprocessing. In your case the error is a linker error LNK2005, and it means that the same symbol was defined in multiple translation units (in your case in each translation unit that includes the header with the definition).



回答2:

If the global variable is not const(*), you cannot put it in a header file and include it in multiple translation units (i.e. .cpp files). Otherwise, you will end up with multiple definitions of the same symbol in your program, violating the ODR (One Definition Rule, see Paragraph 3.2 of the C++11 Standard), and the linker will complain about that.

You should use the extern modifier in your shared header to provide only a declaration of your variable:

extern int var;

Then, in one single .cpp file, you can provide a definition for it:

int var;

(*) const global variables have internal linkage by default, so each translation unit will end up having a private copy of it and no multiple definition will occur.



回答3:

if you insist on having a global variable at least put it in a namespace to avoid collisions with other modules

namespace globals
{
  extern int x;
}

then in the .cpp file define it.

int globals::x = 0;

it also makes it more clear that it is a global variable.