[SOLVED] Preprocessor Directives, boost, and winsock.h already included
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199
Rep:
Preprocessor Directives, boost, and winsock.h already included
I have a program I developed on a Mac, and am trying to get it to compile on Windows.
I have been getting this error:
WinSock.h has already been included.
It appears to have close connection with boost::asio.
I have googled it and tried suggestions from previous posts, but am still getting the error.
I have tried adding WIN32_LEAN_AND_MEAN before any boost/asio include, and before any windows.h includes. Also, I've tried adding asio before windows.h.
I've added my own # error directives to try and track the error down.
One thing I don't understand, and am hoping someone would know why it would be doing this (or if it should not). To simplify:
In one file, I have
Code:
#ifndef THISFILE
#define THISFILE
# ifdef _WINSOCKAPI_
# error Winsock Was Defined here!!
#endif
#endif
I am compiling w/ Visual Studio 2010. I am seeing this error pop up twice, like the file was being processed twice? But I thought the #ifndef....#endif would prevent that?
Any suggestions to help track down the cause appreciated.
Last edited by vendtagain; 10-28-2011 at 04:37 PM.
The inclusion guards only prevent the file from being included more than once in a single module. If you have two or more modules that are including the header file, then you would indeed see your warning message multiple times.
You can also consider experimenting with the "#pragma once" preprocessor directive, however I've never tried it myself.
The inclusion guards only prevent the file from being included more than once in a single module. If you have two or more modules that are including the header file, then you would indeed see your warning message multiple times.
You can also consider experimenting with the "#pragma once" preprocessor directive, however I've never tried it myself.
This isn't the case here.
Haven't done much socket programming, but as far as I can tell, windows has two files - winsock.h and winsock2.h, and windows.h includes winsock.h by default (without LEAN_AND_MEAN). Both winsock.h and winsock2.h define similar types (like SOCKET) and have similar functions, but correspond to different versions of winsock api. boost asio uses winsock2. If you were able to include both headers at once, there will be conflicts - for example, both headers have WSAData typedef. Also, it is very likely that if you were able to include one header in one place and another one in another, there will be many hilarious problems.
I believe there may be a good reason for this scheme (backward compatibility or something, perhaps?), but most likely in order to know the reason I should have been seen transition from winsock1 to winsock2 myself. And as I said, I haven't done much of a network programming.
P.S> By the way was it that hard to look through the headers?
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199
Original Poster
Rep:
I have also checked the headers that include windows.h and boost/asio. Windows.h is only included in one header, any h/cpp files that use windows.h includes the header that has windows.h. boost/asio is only used by one class, and only located in that classes header file.
Last edited by vendtagain; 10-28-2011 at 05:33 PM.
I have also checked the headers that include windows.h and boost/asio. Windows.h is only included in one header, any h/cpp files that use windows.h includes the header that has windows.h. boost/asio is only used by one class, and only located in that classes header file.
Which means that half of your code indirectly includes boost asio (which includes winsock2), and another half indirectly includes windows.h that includes winsock.h. You have a design problem. The quick and dirty solution would be to define WIN32_LEAN_AND_MEAN for the entire project within project settings. The proper solution would be to fix the header mess.
I include the above header multiple places, and according to msdn.microsoft.com the lean_and_mean macro prevents windows.h from including winsock.h.
I have verified that no other windows.h is being included anywhere else in my project, I have used 'grep' tool to check this. So by the time windows.h is included in my project: the WIN32_LEAN_AND_MEAN macro is defined already so windows.h should not by including winsock.h.
Including header that includes header that includes header that includes windows.h is same thing as including windows.h directly. And last time I checked grep doesn't know how to parse C++ code and search for recursive #includes. So, according to murphy's law you have some external library header that indirectly includes windows.h and you use that header in every file of the project.
cl.exe has several command-line switches that allow you to save preprocessed output somewhere (/P /EP in "Configuration->C++->Preprocessor"). Use them. OR you could enable LEAN_AND_MEAN for entire project within project settings.
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199
Original Poster
Rep:
I got it to compile by adding the win32_lean_and_mean to the project's preprocessor definitions. I'm still not sure how windows.h would be included before anything else and I'd rather get it working w/o having to add to the preprocessor def, maybe through some of the other boost libs I was using, link bind or function.
Well, that'll solve the problem for now, I've been working all day on this, thanks for the help.
I'm still not sure how windows.h would be included before anything else and I'd rather get it working w/o having to add to the preprocessor def, maybe through some of the other boost libs I was using, link bind or function.
windows.h is an EXTREMELY "popular" header on windows platform, and it is frequently indirectly included from within other headers. If you can use windows types within *.cpp file (HANDLE, HINSTANCE, DWORD, WORD), then this *.cpp file has windows.h included. To find the "offending" header that includes windows.h you could either remove includes one by one and see which one adds windows.h (just declare DWORD variable anywhere - if it compiles, you have windows.h included), OR you could examine preprocessed compiler output (/E and /P cl.exe switches I mentioned before).
If you want to prevent this from happening, you should avoid #including other headers in *.h files unless it is absolutely necessary (include everything you need from within *.cpp) and use forward-declarations when possible. There is a very small number of situations when you absolutely have to include header:
When you use variable of non-pointer type that is declared within other header. (#include header that has the type)
When you dereference pointer to forward-declared type.
When you derive from class that is declared within other header. (#include header that declares class)
When you use inline function from other header. (#include header that has the function)
When you use template function from other header(#include header that has the function)
When you delete forward-declared class from within inline function (#include header that declares the class)
In all other situations, you can avoid #including things within *.h, and put all #includes into cpp. This also might speed up compilation speed. If you're interested, you could check out Qt 4 examples - it is a good example of such style - nearly everything is forward-declared in *.h, and headers are mostly included within *.cpp.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.