1

I know, there are a lot of similar problems and solutions already on SO, and I read them, but none of them helped me solve my problem.

I created a class for logging. Here is Logger.h

#ifndef LOGGER_H
#define LOGGER_H

namespace Logger
{
namespace debug
{

    int Error = 0, OtherNumber;

    class log
    {
    public:     // Methods
        void Save();

    private:    // Members
        static int indentation;
        const std::wstring context;
        int Type, LineNumber;

    public:     // Constructor, Destructor
        log( const std::wstring& context, int LineNumber, int Type );
        ~log();

    };//class log

}//namespace debug

}//namespace Logger

#endif //LOGGER_H

Logger.cpp

#include "stdafx.h"

#include "Logger.h"

namespace Logger
{
namespace debug
{
    log::log( const std::wstring& ctx, int linenr, int type ): context( ctx ), LineNumber( linenr ), Type( type )
    {
        printf("\nLogging start! Context = %ls - Line = %d - Type = %d", context.c_str(), LineNumber, Type );
    }

    log::~log()
    {
        printf( "\nLogging end! Context = %ls - Line = %d - Type = %d", context.c_str(), LineNumber, Type );
        printf( "\nUsing Error here =%d", Error );
    }
    void log::Save()
    {
        FILE *fp = NULL;

        fclose( fp );
        fp = fopen( "mylogfile.log", "a" );
    }

}//namespace debug

}//namespace Logger

Then in main.h I have:

#ifndef MYAPP_H
#define MYAPP_H

#include "Logger.h"

#define WIDEN2( x )     L ## x
#define WIDEN( x )      WIDEN2( x )
#define WFILE       WIDEN( __FILE__ )

#define __STR2WSTR( str )   L##str
#define _STR2WSTR(str)  __STR2WSTR(str)
#define WFUNCTION       _STR2WSTR( __FUNCTION__ )

#define DEBUGLOG_START( Type )  Logger::debug::log _debugLog( WFUNCTION, __LINE__, Type );
#define DEBUGLOG_SAVE   { _debugLog.Save(); }

#endif //MYAPP_H

And finally in main.cpp I have:

#include "Test_UserPart.h"


int _tmain(int argc, _TCHAR* argv[])
{

DEBUGLOG_START( 1 )

Logger::debug::OtherNumber = 10;

_getch();
return 0;
}

When I want to compile it I get the error error LNK2005: "int Logger::debug::Error" (?Error@debug@Logger@@3HA) already defined in Logger.obj ...MyApp.obj

So as far as I see, I didn't make any circular includes. But why do I get this error?

Thanks!

kampi
  • 2,362
  • 12
  • 52
  • 91

1 Answers1

1

You're defining variables in the header, leading to multiple definitions when that header is included from more than one source file. Instead, declare them in the header:

extern int Error = 0, OtherNumber;
^^^^^^

and define them in just one source file. Or stop using global variables.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Maybe I am doing something wrong, but now I get: `unresolved external symbol` errors. In the `Logger.h` now I have `extern int Error;`, and in `main.cpp` I have `::Logger::debug::Error = 0;` Unfortunately some values must be globals. Or can I some other way access them, form main? – kampi May 05 '15 at 18:07
  • never mind I figured it out! Thanks! – kampi May 05 '15 at 19:33
  • @kampi what did you figure out? – Ollie Dec 18 '18 at 03:29
  • @Ollie: sorry I don't remember. This was more than 3 years ago, but probably I meant, how to access the variables. I don't have access to this code any more unfortunately. – kampi Dec 19 '18 at 12:01
  • @Ollie, 5 years later and I also fell in this question!.. I believe the answer could use a clarification. Just do the actual declaration in one and only one source file without the `extern`, and assigning the global variable's initial value (`0` in the case of `Error` above).. – Avenger Mar 02 '23 at 12:28