Reputation: 3
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 pragma once 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"
Upvotes: 0
Views: 5110
Reputation: 43380
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;
Upvotes: 0
Reputation: 503795
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.
Upvotes: 2
Reputation: 53934
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).
Upvotes: 0