views:

161

answers:

4

i am trying to use following pattern.

#ifndef TRACER_H
#include "Tracer.h"
#endif

This is statement is added to each file in the code such that tracer.h is added only once. Still i am getting an error saying multiple objects

Also Tracer.h contains

#ifndef TRACER_H
#define TRACER_H

here is the error i tried prgma onece as well

1>Generating Code...
1>Linking...
1>LINK : \\stu05-fsrv.ad.syr.edu\akbhat$\Visual Studio 2008\Projects\Project3\Debug\Project3.exe not found or not built by the last incremental link; performing full link
1>SemiExpression.obj : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class tracer &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVtracer@@@Z) already defined in main.obj
1>SemiExpression.obj : error LNK2005: "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > tracer::log" (?log@tracer@@0V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A) already defined in main.obj
1>Tokenizer.obj : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class tracer &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVtracer@@@Z) already defined in main.obj
1>Tokenizer.obj : error LNK2005: "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > tracer::log" (?log@tracer@@0V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A) already defined in main.obj
1>\\stu05-fsrv.ad.syr.edu\akbhat$\Visual Studio 2008\Projects\Project3\Debug\Project3.exe : fatal error LNK1169: one or more multiply defined symbols found
1>Build log was saved at "file://\\stu05-fsrv.ad.syr.edu\akbhat$\Visual Studio 2008\Projects\Project3\Project3\Debug\BuildLog.htm"
A: 

If tracer.h contains what you claim it does and the ifndef contains the whole tracer.h inside it then you don't need this construct at all.

Let_Me_Be
yes it contains the guardstill it is giving the error at link time
john
obviously it didn't...
Let_Me_Be
A: 

Maybe you want to read about include guards. They should provide what you are looking for. And they are a well known standard pattern for your case.
Depending on your compiler the #pragma once could be interesting, too. And maybe you read pragma vs. guard here on SO (there are a lot more good questions about both on SO).

tanascius
+1  A: 

Firstly, header guards go inside the file. It makes it much easier:

// some_header.h
#ifndef SOME_HEADER_INCLUDED_H
#define SOME_HEADER_INCLUDED_H

// ...

#endif

Secondly, these guards only protect from multiple includes per-translation-unit. If you have main.cpp and foo.cpp, and each contains:

#include "some_header.h"
#include "some_header.h" // again

// ...

The contents in-between the include guards will be included only once per-unit, but will be defined twice, one in each unit.

When link time comes, you'll get multiple-definition errors. You need to have those static variables defined in one source file, and only declare it in the header.

GMan
it seems to be a correct answer let me check
john
i created Tracer.cpp and defined the static variable log in that file. yet when i inculde Tracer.h in multiple files i still end up with same error
john
Thanks it workedthere were two static objects
john
@john: Glad it's working for you. :]
GMan
A: 

I think you forgot to put #endif after #ifdef in your include guard. Just use this pattern in your header files:

#ifndef HEADERNAME_H
#define HEADERNAME_H

/* code */

#endif

Also, you may be declaring object instances in header files, which end up being duplicated across all your source files and resulting in linking errors. I'd need to see some more code to see where the exact problem is, but if you say this in a header file:

Foo myInstance;

You'll get linker errors because the symbol myInstance refers to multiple instances (one for each .cpp file that includes it) instead of one. Instead, put the above line in a .cpp file, and put this in your header:

extern Foo myInstance;
Joey Adams