Resolving Redefinition Errors Betwen ws2def.h and winsock.h

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
If the #pragma option above is unfamiliar to you, the compiler passes it along to the linker telling it to include the lib rather than having to set it in the project settings. Theres more on #pragma comment options over on MSDN.

Comments

6 responses to “Resolving Redefinition Errors Betwen ws2def.h and winsock.h”

  1. John Avatar
    John

    Thanks, Zach.
    Your post saved me hours of grief.

    1. ZachB Avatar

      Glad you found it useful!

  2. Oren Avatar
    Oren

    FYI – option 2:
    I just spend a few very annoying hours trying to resolve an issue with struct alignment and size. At the end it all boiled down to including winSock2 before windows.
    apparently it messes with structs packing size and caused some system calls to fail because the given struct was reported as size 36 instead of 40.
    to summarize – use solution 2 with caution. prefer other solutions if possible.

    to see the issue happening try the following code:

    #pragma pack(8)
    		typedef struct _FILE_BASIC_INFO {
    			LARGE_INTEGER CreationTime;
    			LARGE_INTEGER LastAccessTime;
    			LARGE_INTEGER LastWriteTime;
    			LARGE_INTEGER ChangeTime;
    			DWORD FileAttributes;
    	} FILE_BASIC_INFO, *PFILE_BASIC_INFO;
    
    	int size =  sizeof(FILE_BASIC_INFO);
    

    — the expected size (by the OS, and by looking at the struct is 40. However, after winsock2 did its thing (still not sure what it does), We get a size of 36, which in turn causes some system calls to fail.

    1. ZachB Avatar

      Ahhh, interesting Oren! It looks like if WIN32 isn’t defined before including Winsock2.h that the structure sizes get messed up. winsock2.h messes up structure packing

      In my quick testing it looks like if you define WIN32 before including Winsock2.h using option 2 (either in your code explicitly or setting the preprocessor flag in your project settings) then you get the correct struct sizes.

  3. DiGMi Avatar

    Thanks, That was helpful. I had the same problem trying to include ZeroMQ in a project I’m working on. #define WIN32_LEAN_AND_MEAN did the trick.

  4. MichaelK Avatar
    MichaelK

    Very helpful. Defining #define WIN32_LEAN_AND_MEAN before any of my #includes fixed it.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.