LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-28-2011, 04:34 PM   #1
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Rep: Reputation: 32
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.
 
Old 10-28-2011, 05:05 PM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
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.
 
Old 10-28-2011, 05:11 PM   #3
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
What do you mean by module?
 
Old 10-28-2011, 05:15 PM   #4
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 234Reputation: 234Reputation: 234
Quote:
Originally Posted by dwhitney67 View Post
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?

Last edited by SigTerm; 10-28-2011 at 05:19 PM.
 
Old 10-28-2011, 05:32 PM   #5
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
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.
 
Old 10-28-2011, 05:39 PM   #6
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 234Reputation: 234Reputation: 234
Quote:
Originally Posted by vendtagain View Post
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.

Last edited by SigTerm; 10-28-2011 at 05:42 PM.
 
Old 10-28-2011, 06:09 PM   #7
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
I have
Code:
#ifndef WIN_DEFS
#define WIN_DEFS

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#endif
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.
 
Old 10-28-2011, 06:22 PM   #8
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 234Reputation: 234Reputation: 234
Thumbs down

Quote:
Originally Posted by vendtagain View Post
I have used 'grep' tool to check this.
That is not enough.

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.

Last edited by SigTerm; 10-28-2011 at 06:27 PM.
 
Old 10-28-2011, 06:53 PM   #9
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
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.
 
Old 10-29-2011, 05:25 AM   #10
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 234Reputation: 234Reputation: 234
Quote:
Originally Posted by vendtagain View Post
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:
  1. When you use variable of non-pointer type that is declared within other header. (#include header that has the type)
  2. When you dereference pointer to forward-declared type.
  3. When you derive from class that is declared within other header. (#include header that declares class)
  4. When you use inline function from other header. (#include header that has the function)
  5. When you use template function from other header(#include header that has the function)
  6. 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.

Last edited by SigTerm; 10-29-2011 at 05:27 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C pre-preprocessor or preprocessor replacement Tischbein Programming 3 02-11-2007 11:38 AM
Man pages available for C Preprocessor directives? BiThian Linux - General 1 10-22-2006 12:50 PM
communicating with winsock through linux mrobertson Linux - Newbie 1 05-26-2005 02:24 AM
Winsock problem with wine jrmontg Linux - Software 2 01-18-2005 03:59 PM
Winsock using QT Boffy Programming 0 10-27-2004 03:29 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:57 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration