views:

5018

answers:

9

How do I prevent from including header files twice? The problem is I'm including the in MyClass.h and then I'm including MyClass.h in many files, so it includes multiple times and redefinition error occurs. How to prevent?

I'm using #pragma once instead of include guards, and I guess that's fine.

MyClass.h:

// MyClass.h
#pragma once

#include <winsock2.h>

class MyClass
{

// methods
public:
 MyClass(unsigned short port);
 virtual ~MyClass(void);
};

EDIT: Few of the errors I'm getting

c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(91) : warning C4005: 'AF_IPX' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(460) : see previous definition of 'AF_IPX'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(124) : warning C4005: 'AF_MAX' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(479) : see previous definition of 'AF_MAX'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(163) : warning C4005: 'SO_DONTLINGER' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(402) : see previous definition of 'SO_DONTLINGER'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(206) : error C2011: 'sockaddr' : 'struct' type redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(485) : see declaration of 'sockaddr'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(384) : error C2143: syntax error : missing '}' before 'constant'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(384) : error C2143: syntax error : missing ';' before 'constant'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(384) : error C2059: syntax error : 'constant'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(437) : error C2143: syntax error : missing ';' before '}'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(437) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(437) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(518) : warning C4005: 'IN_CLASSA' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(287) : see previous definition of 'IN_CLASSA'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(524) : warning C4005: 'IN_CLASSB' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(293) : see previous definition of 'IN_CLASSB'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(530) : warning C4005: 'IN_CLASSC' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(299) : see previous definition of 'IN_CLASSC'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(541) : warning C4005: 'INADDR_ANY' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(304) : see previous definition of 'INADDR_ANY'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(543) : warning C4005: 'INADDR_BROADCAST' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(306) : see previous definition of 'INADDR_BROADCAST'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(577) : error C2011: 'sockaddr_in' : 'struct' type redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(312) : see declaration of 'sockaddr_in'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(132) : error C2011: 'fd_set' : 'struct' type redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(68) : see declaration of 'fd_set'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(167) : warning C4005: 'FD_SET' : macro redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(102) : see previous definition of 'FD_SET'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(176) : error C2011: 'timeval' : 'struct' type redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(111) : see declaration of 'timeval'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(232) : error C2011: 'hostent' : 'struct' type redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(167) : see declaration of 'hostent'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(245) : error C2011: 'netent' : 'struct' type redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(180) : see declaration of 'netent'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(252) : error C2011: 'servent' : 'struct' type redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(187) : see declaration of 'servent'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(264) : error C2011: 'protoent' : 'struct' type redefinition
        c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(199) : see declaration of 'protoent'
+9  A: 

By using "header guards":

#ifndef MYCLASS_H
#define MYCLASS_H

// MyClass.h
#pragma once

#include <winsock2.h>

class MyClass
{

// methods
public:
    MyClass(unsigned short port);
    virtual ~MyClass(void);
};

#endif
DevSolar
I guess I am wrong (4 upvotes by now), but I think using include guards is the same as pragma once, you put them both?
Svetlozar Angelov
Well, I have #pragma once which afaik is the same header guards
hab
@Angelov: Yes, that's what I'm saying they are the same things. The problem is not with my header files, but I think <winsock2.h> itself doesn't have header guards or may be something else.
hab
@Manzoor: What is the problem your trying address then?
Naveen
The problem is that I include <winsock2.h> in my header and then in another header I include my previous header file and so comes the redefinition of WinSock2 structures. Why?
hab
`#ifndef/#defined` include guards are fully portable standard c++. The behaviour of `#pragma once` is implementation dependent although many implementations make it behave exactly as include guards would.
Charles Bailey
#pragma once relies on compiler, it's not the same as header guard, which is more portable
Fu4ny
By definition #pragma is compiler dependent (non-standard). It may not work on all compilers. I know that visual studio accepts #pargma once. I'm not sure if gcc does. I know that include guards ALWAYS work. I use both #pragma once and include guards for maximum protability. It seems that MSVC has optimized handling of #pragma once and gcc has optimized handling of include guards. The only difference with my standard header is that #praga once is outside the include guards.
KitsuneYMG
The '#pragma' command is specified in the ANSI standard to have an arbitrary implementation-defined effect. In the GNU C preprocessor, '#pragma' first attempts to run the game 'rogue'; if that fails, it tries to run the game 'hack'; if that fails, it tries to run GNU Emacs displaying the Tower of Hanoi; if that fails, it reports a fatal error. In any case, preprocessing does not continue.-- Richard M. Stallman, The GNU C Preprocessor, version 1.34
DevSolar
Above comment posted to stress that #pragma does "something", while #ifndef / #define / #endif is fully portable, standard compliant, and recommended practice. @ Manzoor Ahmed: Try to boil down your problem to the minimum amount of code required to reproduce it. It's a very useful practice for debugging such problems.
DevSolar
@ Svetlozar Angelov: I retained the #pragma once from the original code, not being 100% sure what it does, and simply wrapped the whole thing. Shouldn't hurt either way.
DevSolar
Yea, but none of the solutions solved the problem
hab
Then your problem is not related to multiple inclusions of MyClass.h. Again: Make a copy of your code, then methodically cut away files and source lines not necessary to reproduce the error, until you see the problem. Trust me, works every time.
DevSolar
Thanks, I'll try myself.
hab
pragma one is known to be faster than header guard, but it's not standard. So sometimes developer use both of them.
Fu4ny
If "faster" really does matter to you, you can "header-guard" the #include statement (in the including source). That way the compiler doesn't even have to open the header file the second time around.
DevSolar
@DevSolar: you're way out of date. GCC has supported #pragma once for years.
Steve Jessop
@onebyone: That Richard Stallman quote was *humor*. You know? Like when you tell people that relying on undefined behaviour might format their hard drives...
DevSolar
I know, but the questioner isn't relying on undefined behaviour, and Stallman's quote is not applicable. He's relying on defined behaviour of his compiler (just not defined in the C++ standard). So #pragma doesn't do "something", it does exactly what it says in MS's documentation. Accuse me of humourlessness, I'll accuse you of derailing the conversation, someone can chip in with a Nazi analogy, and we'll have the usenet trifecta ;-)
Steve Jessop
Hrr, hrr... I'm game. :-D You might want to note, though, that the original, unedited post I was referring to did *not* state the compiler being used...
DevSolar
Yeah, true. I'm now planning a filter for SO that looks at code snippets in questions, identifies compiler-specific code, and forces the questioner to specify compiler if there is any. Detecting code that relies on 2's complement arithmetic could be tricky, though...
Steve Jessop
+2  A: 

You should use header guard.

put those line at the top of the header file

#ifndef PATH_FILENAME_H
#define PATH_FILENAME_H

and at the bottom

#endif
Fu4ny
#pragma once and include guards are same things aren't they?
hab
They are not quite the same - the header guards will prevent re-inclusion of the file at the preprocessor level, plus they're obviously a tad more portable than #pragma once.
Timo Geusch
I meant they are built for the same purposes :)
hab
#pragma once is non-standard, afaik
Fu4ny
+3  A: 

#pragma once is flakey, even on MS compilers, and is not supported by many other compilers. As many other people have mentioned, using include guards is the way to go. Don't use #pragma once at all - it'll make your life much easier.

Thomi
Unfortunately, I've seen more than zero botched include guards, either where a typo means the guard doesn't actually work, or where files of the same name in different directories use the same token, or where the token used begins with a double underscore or underscore then capital-letter (and hence is non-portable just like #pragma once). So for inherently non-portable code, like anything using winsock.h, I was deeply untroubled by #pragma once right up to the point you said it was flakey. When does it fail, other than not being supported at all?
Steve Jessop
When using `#pragma once`, the compiler takes the header file node name as the unique Id. This can fail if you have symbolic links or NTFS junctions in your source tree (more common than you might think), or even if you have a file of the same name in another system include directory (this has happened to me before when I has version 1 and version 2 of the same library installed to two different system include paths).Bottom line: for me, I prefer to have more control, and live with the occasional wetware mistake, rather than trust a compiler to do it for me.
Thomi
+2  A: 

#pragma once is based on the full path of the filename. So what you likely have is there are two identical copies of either MyClass.h or Winsock2.h in different directories.

soru
a symbolic link or NTFS junction will also cause the system to break.
Thomi
+1  A: 

#include guards are the standard way of doing this. #pragma once is not, meaning that not all compilers support it.

Dima
+9  A: 

This problem is caused when including <windows.h> before <winsock2.h>. Try arrange your include list that <windows.h> is included after <winsock2.h> or define _WINSOCKAPI_ first:

#define _WINSOCKAPI_    // stops windows.h including winsock.h
#include <windows.h>
// ...
#include "MyClass.h"    // Which includes <winsock2.h>

See also this.

pingw33n
I'm not including <windows.h> at all, I know <winsock2.h> does its for me.
hab
For me your code compiles ok with only `<winsock2.h>` in MSVC2008. `<windows.h>` inclusion makes it generate identical compile errors as you provided.
pingw33n
Is <windows.h> being included in stdafx.h?
Colin Desmond
+2  A: 

I wouldn't use just FILENAME_H but

#ifndef FILENAME_H_AF06570D_B36E_4B82_8F97_C456AF4A38FD
#define FILENAME_H_AF06570D_B36E_4B82_8F97_C456AF4A38FD

//code stuff
#endif // FILENAME_H_AF06570D_B36E_4B82_8F97_C456AF4A38FD

I have always used a postfix guid. I came across a very poor code base some years ago that had different header files with the same file name and include guard. The files in question had defined a class with the same name. If only namespaces were used. Some projects compiled some didn't. Using unique guards was a part of the solution in differentiating headers and their contents.

On Windows with Visual Studio use guidgen.exe, on Linux uuidgen -t.

Sam
A: 

I ran into this problem when trying to pull a third party package which was apparently including windows.h somewhere in it's mess of headers. Defining _WINSOCKAPI_ at the project level was much easier (not to mention more maintainable) than wading through their soup and fixing the problematic include.

Yaur
+1  A: 

Oh - the ugliness of Windows... Order of includes are important here. You need to include winsock2.h before windows.h. Since windows.h is probably included from your precompiled header (stdafx.h), you will need to include winsock2.h from there:

#include <winsock2.h>
#include <windows.h>
Daniel Paull