在WinSock2.h中,无效的套接字和套接字错误被定义为这些?这有什么意义吗?
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
答案 0 :(得分:31)
很久以前,在一个寒冷的雨天清晨,在华盛顿州西雅图一个古朴但不断发展的郊区,绿色覆盖的山丘中间,有一小片但又庞大的红砖建筑群,在一个其中一个是中型会议室,越来越多的网络软件工程师,经理和建筑师聚集在一起。会议已经开始悄悄地开始了,大多数男性组都喝着茶和咖啡,在他们的便笺上乱涂他们的机械铅笔,或者在他们的Palm Pilots上划伤(有那个的家伙与牛顿,但每个人都不理睬他。)
当演示者继续浏览源代码时,他被5位软件架构师中的一位拦截,这些架构师没有被邀请参加评审,但无论如何都出现了。 “什么,祈祷告诉,那个。”他说,像克林顿总统一样摇着他的手指。主持人停下来,盯着手指,发现自己被手指的摆动迷住了,因为建筑师继续摇摆。 “我说,”他开始重复。
主持人抬头看着屏幕,没有注意到任何不对劲。 “你在说什么?”他问道。
建筑师抬起眉毛,因为他的脸首先表示惊愕,然后转向愤怒,然后便秘,因为他大喊“那是一种明显的编码风格指导违规!”。
观察者们开始互相窃窃私语,想知道问题究竟是什么。但是,主持人不知所措(第二种),很快就感谢您的反馈,并继续进行审查。
“我将不被忽略!”,当他突然站起来时,建筑师尖叫着尖叫着,用一种懦弱的砰砰声将他的手掌猛地撞到桌面上。 / p>
当拳头敲打桌子时,房间爆发了,经理们开始设计掩盖他们背后的方法,工程师开始翻阅他们的编码风格手册,包括目录,索引,脚注和参考文献。
主持人在外面没有受到干扰,但感到很生气,因为他非常想要完成审查,以便他可以继续他的Snoqualmie滑雪之旅。 “你在谈论类型不匹配吗?”,他随口问道。
建筑师看了一会儿看起来很吃惊,但很快就重新组合了自己,“显然”,他哼了一声。
演示者用“〜0”替换了两个字符“-1”并转过身来。建筑师仔细检查了变化,然后是屏幕的其余部分,然后咨询了他的笔记,然后终于坐下来了。
其余的评论平安无事。
答案 1 :(得分:18)
在二进制补码系统上(Windows总是两个补码),~0
等于-1
,因此对编译器没有意义。
对读者可能有意义:~0
强调它是一个设置了所有位的值,而-1
强调它是一个小于0的值。
除了:
在不是二进制补码的系统上,假设SOCKET
是无符号类型,编写(SOCKET)(~0)
通常错误。原因是在这样的系统上,~0
不代表值-1,它是INT_MIN
,负零或陷阱表示之一。因此,它不一定会转换为类型SOCKET
作为所有位为零的值,而是转换为INT_MAX+2
,0
或goodness-knows-what(也许是全部的值)位设置)。
因此,通常应使用-1
初始化无符号类型,以获取设置了所有位的值。如果您知道要处理的是哪种无符号类型,可以使用UINT_MAX
或~0UL
或类似内容。但这不值得,因为-1
适用于所有无符号类型。
答案 2 :(得分:3)
主要是邋.. -1和~0实际上是一样的。
你可能会认为~0是更好的样式,因为socket是一个unsigned int,但实际上它对任何实际目的都没有任何影响。
因为他们使用“#define”而不是“const unsigned”,你仍然对陌生感持开放态度。 e.g。
unsigned a = SOCKET_ERROR;
long long b = a;
if (b != SOCKET_ERROR)
std::cout << "????\n";
可能会给一些人一个惊喜。
答案 3 :(得分:0)
因为SOCKET是无符号的,所以不能使用(-1)。
答案 4 :(得分:0)
INVALID_SOCKET
用于返回SOCKET
的函数,这是一个指针(很像HANDLE
)。在32位系统上,它将是32位值,而在64位系统上,它将是64位值。
如果正确转换为等效大小的整数,则与-1
相同。但是,如果不假设它将始终被正确演绎则更安全。
答案 5 :(得分:0)
每个(-1)是(~0)但不是每个(~0)都是(-1)。