0

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"
Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
john
  • 3
  • 1
  • 3

3 Answers3

2

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.

GManNickG
  • 459,504
  • 50
  • 465
  • 534
  • 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 Apr 18 '10 at 20:17
0

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).

Community
  • 1
  • 1
tanascius
  • 50,043
  • 21
  • 106
  • 130
0

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
  • 37,814
  • 17
  • 79
  • 110