Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"WinSock.h has already been included" #1441

Open
apolukhin opened this issue Mar 6, 2024 · 2 comments
Open

"WinSock.h has already been included" #1441

apolukhin opened this issue Mar 6, 2024 · 2 comments

Comments

@apolukhin
Copy link

There's a feature request to Boost.Stacktrace boostorg/stacktrace#155 that look like should go to ASIO:

"""
The order in which you include stacktrace.hpp & asio.hpp can cause a compilation error on Windows.
I tested this on MSVC 19.34.31947 with Boost 1.84.0.

For example, this code doesn't compile:

#include <boost/stacktrace/stacktrace.hpp>
#include <boost/asio.hpp>

This is the error message:

boost\asio\detail\socket_types.hpp(24): fatal error C1189: #error:  WinSock.h has already been included

It compiles fine if you swap the order:

#include <boost/asio.hpp>
#include <boost/stacktrace/stacktrace.hpp>

The same code compiles without issue on Linux (tested with gcc 10 on Debian 11).
This isn't really a huge problem as all you have to do to fix it is include socket_types.hpp before stacktrace.hpp, but the inconsistency is weird when cross-compiling.
"""

@mabrarov
Copy link

mabrarov commented Mar 6, 2024

Hi @apolukhin,

socket_types.hpp(24) has following check:

# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
#  error WinSock.h has already been included
# endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)

and WinSock2.h (part of Windows SDK, installed with Visual Studio 2019 in my case) has

#ifndef _WINSOCK2API_
#define _WINSOCK2API_
#define _WINSOCKAPI_   /* Prevent inclusion of winsock.h in windows.h */

It seems that Asio just checks if winsock.h was included instead of WinSock2.h. Similar check exists in ws2def.h too:

#if !defined(_WINSOCK2API_) && defined(_WINSOCKAPI_)
#error Do not include winsock.h and ws2def.h in the same module. Instead include only winsock2.h.
#endif

Maybe winsock.h comes to Boost.Stacktrace headers within Windows.h which has following code:

#ifndef _MAC
#if defined(_68K_) || defined(_MPPC_)
#define _MAC
#endif
#endif
...
#ifndef WIN32_LEAN_AND_MEAN
...
#ifndef _MAC
#include <winperf.h>
#include <winsock.h>
#endif
...
#endif

_MAC and _68K_ make me suspecting that reporter of boostorg/stacktrace#155 has some specific build environment / configuration which needs to be fixed (and Asio just did a good job by highlighting that).

Sorry, I misread last #ifndef _MAC as #ifdef _MAC, so the strikethrough part of my comment is not correct.

@mabrarov
Copy link

mabrarov commented Mar 6, 2024

It looks like there is no way for Asio to solve this issue:

  1. https://stackoverflow.com/questions/21399650/cannot-include-both-files-winsock2-windows-h
  2. https://stackoverflow.com/questions/9153911/is-there-a-difference-between-winsock-h-and-winsock2-h

The most of Windows builds I know use WIN32_LEAN_AND_MEAN macro. Maybe it's the only solution for boostorg/stacktrace#155. Replacing every

#include <windows.h>

with something like

#ifdef WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#endif

in Boost (because it is not just Boost.Stacktrace who includes windows.h) seems to be overkill (though some Boost libraries define WIN32_LEAN_AND_MEAN in compilation units and / or in Jamfiles).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants