'fd_set' redefinition winsock2.h,相关头文件条件编译处理

在Win32 Console Application开发中遇到错误,由于winsock.h和winsock2.h中fd_set结构体的重定义导致编译失败。解决方法包括在引用<windows.h>前定义WIN32_LEAN_AND_MEAN或首先引用<winsock2.h>。第一种方法可能导致其他头文件未被引入,更优的解决方案是定义/_WIN32_WINNT 0x0400。第二种方法利用头文件中定义的_WINSOCKAPI_宏,使得<winsock.h>被跳过。通过理解这些头文件的包含机制,可以避免冲突并成功编译。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天写一个TCP/IP的小程序的时候,偶然间发现一个错误

工程类型:Win32 Console Application

 

错误如下:

--------------------Configuration: TcpSer - Win32 Debug--------------------
Compiling...
main.cpp
d:/program files/microsoft visual studio/vc98/include/winsock2.h(99) : error C2011: 'fd_set' : 'struct' type redefinition
d:/program files/microsoft visual studio/vc98/include/winsock2.h(134) : warning C4005: 'FD_SET' : macro redefinition
        d:/program files/microsoft visual studio/vc98/include/winsock.h(83) : see previous definition of 'FD_SET'

.....

.....


TcpSer.exe - 65 error(s), 11 warning(s)

 

一看的我就头大了,怎么可能会报错呢?

看了看错误原因,可能是因为winsock.h和winsock2.h中有重定义的部分

从网上随便搜了搜,也有说到解决办法的,两种方式:

1、在引用<windows.h>之前,加上预处理指令:#define WIN32_LEAN_AND_MEAN ,其实,这也是VS预编译头stdafx.h中使用到的一条指令。

2、就是在引用<windows.h>之前,引用<winsock2.h>

 

用了以后,当然,问题是解决了,但是,为什么呢?

 

对于方法一奏效的原因:有不妥之处,下面有讲解

打开<winsock2.h>中间有几条指令

#ifndef WIN32_LEAN_AND_MEAN
#include <cderr.h>
#include <dde.h>
#include <ddeml.h>
#include <dlgs.h>
#ifndef _MAC
#include <lzexpand.h>
#include <mmsystem.h>
#include <nb30.h>
#include <rpc.h>
#endif
#include <shellapi.h>
#ifndef _MAC
#include <winperf.h>

#if(_WIN32_WINNT >= 0x0400)
#include <winsock2.h>
#include <mswsock.h>

#else
#include <winsock.h>

#endif /* _WIN32_WINNT >=  0x0400 */

 

如果,你直接#define WIN32_LEAN_AND_MEAN_,那么,中间有的那些所有的#include的头文件都将没有被引入(虽然说它们不一定会被用到),但是这当然是不妥的。

所以,此时应该将#define WIN32_LEAN_AND_MEAN_改成#define _WIN32_WINNT  0x0400(或者大于0x0400的值)

这时候,就只会将一条#include<winsock.h>指令排除掉,其他的都没有影响。

 

 

对于方法二奏效的原因:

于是,我将3个头文件<windows.h>,<winsock.h>,<winsock2.h>文件打开看了看,

发现,在<winsock2.h>一开始,就有有这么几条指令

 

原来就是它了…

可能还不明白,那么,请看<winsock.h>中一开始的这几条指令

 

上面的方法2之所以能成功,就是因为当你先引用了<winsock2.h>的时候,就会#define _WINSOCKAPI_

当你之后引用<winsock.h>,就会因为此时已经"定义"了 _WINSOCKAPI_而直接跳到<winsock.h>的文件尾,相当于<winsock.h>就没有被包含

 

 

 

附加一句,winsock2.h中有这么一段:

 

所以,在#include<winsock2.h>以后,其实可以不用再#include<windows.h>了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值