The Problem
This particular issue I run into much more frequently than I would like (full pathnames removed for brevity):
ws2def.h(91): warning C4005: ‘AF_IPX’ : macro redefinition
winsock.h(460) : see previous definition of ‘AF_IPX’
ws2def.h(131): warning C4005: ‘AF_MAX’ : macro redefinition
winsock.h(479) : see previous definition of ‘AF_MAX’
ws2def.h(168): warning C4005: ‘SO_DONTLINGER’ : macro redefinition
winsock.h(402) : see previous definition of ‘SO_DONTLINGER’
ws2def.h(212): error C2011: ‘sockaddr’ : ‘struct’ type redefinition
winsock.h(485) : see declaration of ‘sockaddr’
ws2def.h(390): error C2059: syntax error : ‘constant’
ws2def.h(524): warning C4005: ‘IN_CLASSA’ : macro redefinition
winsock.h(287) : see previous definition of ‘IN_CLASSA’
The Cause
The problem is due to an incompatibility between winsock.h and WinSock2.h. This usually occurs when something has included Windows.h (which includes winsock.h) before WinSock2.h, like this:
#include <Windows.h> #include <WinSock2.h> int main( int argc, char* argv[] ) { return 0; }
Of course, finding where this include ordering has occurred is often more complex than this example. Turn on the “Show Includes” compiler option and look in the output window of your build to trace the occurrence to your source files.
The Solution
You basically have three options to fix this:
Option 1: WIN32_LEAN_AND_MEAN
Defining WIN32_LEAN_AND_MEAN will reduce the size of the Windows headers by excluding several APIs, including Windows Sockets.
#define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <WinSock2.h> int main( int argc, char* argv[] ) { return 0; }
Option 2: Explicitly include WinSock2.h before Windows.h
By explicitly including WinSock2.h before every place that you Windows.h, you prevent the collision. However, this can be quite cumbersome at times.
UPDATE 2011-11-12:This method can cause issues with struct packing and alignment if WIN32 isn’t defined before including WinSock2.h (see Oren’s comment below). To resolve this issue, either define WIN32 as a preprocessor flag in your project or explicitly define #WIN32 prior to the WinSock2.h include as I’ve done below.
#ifndef WIN32 #define WIN32 #endif #include <WinSock2.h> #include <Windows.h> int main( int argc, char* argv[] ) { return 0; }
Option 3: Create a WinSock Wrapper Header
This option creates a header file that prevents the collision in the first place and then you include this at (or nearest as possible) to the top of every file that needs WinSock2.h.
The following is based on code from this stackoverflow answer.
#ifndef _WINSOCK_WRAPPER_H_ #define _WINSOCK_WRAPPER_H_ #if _MSC_VER > 1000 #pragma once #endif #ifndef _WINDOWS_ #define WIN32_LEAN_AND_MEAN #include <windows.h> #undef WIN32_LEAN_AND_MEAN #endif #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") #endif
6 thoughts