7

Some code and associated warnings/errors:

#include <windows.h>
#include <iphlpapi.h>
int main() { }

F:/Prog/mingw-w64/x86_64-4.9.2-win32-seh-rt_v3-rev1/mingw64/x86_64-w64-mingw32/include/ws2ipdef.h:71:3: error: 'ADDRESS_FAMILY' does not name a type

ADDRESS_FAMILY si_family;
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
int main() { }     // this compiles successfully, only gives warning

F:/Prog/mingw-w64/x86_64-4.9.2-win32-seh-rt_v3-rev1/mingw64/x86_64-w64-mingw32/include/winsock2.h:15:2: warning: #warning Please include winsock2.h before windows.h [-Wcpp]

#include <winsock2.h>
#include <windows.h>
#include <iphlpapi.h>
int main() { }

(compilation successful).

My questions are:

  • Why doesn't iphlpapi.h (and other files that rely on winsock) do #include <winsock2.h> themself, or at least give a nicer error message?
  • Why does there a warning for it to come before windows.h ?
M.M
  • 138,810
  • 21
  • 208
  • 365
  • About the warning part, the original file from MS has problems with the include order too. Windows.h defines some things of winsock2..h too if they aren´t defined yet, but different. Winsock2.h has to be the first to get the right definitions. – deviantfan Mar 16 '15 at 05:10
  • http://stackoverflow.com/questions/21399650/cannot-include-both-files-winsock2-windows-h addresses this issue too – deviantfan Mar 16 '15 at 05:12
  • @deviantfan that answer seemed to explain that this order was required, but not why – M.M Mar 16 '15 at 05:32
  • For what it's worth, your second example doesn't compile in Visual Studio either, and the mountain of errors is much less friendly. :) – Retired Ninja Mar 16 '15 at 06:52
  • @RetiredNinja it does compile successfully, just gives a `#warning` on the way – M.M Mar 16 '15 at 07:44

1 Answers1

13

windows.h includes winsock.h by default. winsock.h and winsock2.h do not coexist. If winsock2.h is included first, it disables winsock.h, and all is good. But if winsock.h is included first, winsock2.h fails to compile, because it redeclares a lot of things that winsock.h already declares. Thus why you need to include winsock2.h first.

Microsoft wants people to use one or the other, not both. winsock2.h is meant to replace winsock.h rather than supplement it. But why they made winsock2.h so incompatible that it completely breaks if winsock.h is included first is anyone's guess. They could have just as easily made winsock2.h #ifdef any duplicate declarations to avoid errors. Or even have winsock2.h include winsock.h for the declarations. But they didn't.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • mingw-w64 does actually work if you include winsock2 second (it only gives a #warning) . Maybe mingw-w64 doesn't support winsock1 at all, or maybe it went ahead and did those "just as easily" things. – M.M Mar 16 '15 at 06:38
  • I suspect mingw's version of `windows.h` is including `winsock2.h` instead of `winsock.h`, if it is including either one of them at all. – Remy Lebeau Mar 16 '15 at 17:40
  • I don't think it's including either, as my first program would have compiled if so – M.M Mar 16 '15 at 19:32