While using #ifndef, .h file being added multiple times

柔情痞子 提交于 2019-12-14 04:05:36

问题


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"

回答1:


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.




回答2:


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




回答3:


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;


来源:https://stackoverflow.com/questions/2663702/while-using-ifndef-h-file-being-added-multiple-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!