22

在WinSock2.h中,invalid socket和socket error是这样定义的?这有什么意义吗?

#define INVALID_SOCKET  (SOCKET)(~0)
#define SOCKET_ERROR            (-1)
4

6 回答 6

38

很久以前,一个寒冷的雨天的清晨,在华盛顿州西雅图一个古色古香但不断发展的郊区,在雾蒙蒙的绿色覆盖的山丘中,有一小群蔓延的红砖建筑,其中一栋是一个中等大小的会议室,越来越多的网络软件工程师、经理和架构师聚集在这里。会议开始时已经足够安静了,大部分是男性群体,啜饮着他们的茶和咖啡,旋转着他们的自动铅笔,同时在他们的记事本上乱涂乱画,或者在他们的掌上电脑上刮擦(有那个拿着牛顿的人,但每个人都忽略了他)。

当演示者继续滚动浏览源代码时,他被 5 位软件架构师中的一位拦住了,他们没有被特别邀请参加评审,但还是出现了。“请告诉我,那是什么。”他怒火中烧,像克林顿总统一样摇着手指。主持人停下来盯着手指,发现自己不知何故被建筑师继续摇晃时手指的摆动所迷住了。“我说过,”他开始重复。

主持人抬头看着屏幕,并没有发现任何异常。“你在说什么?” 他问。

建筑师挑了挑眉,脸上先是惊愕,然后是愤愤不平,然后是便秘,大喊“是公然违反编码风格准则!”。

观察者之间开始窃窃私语,想知道这到底是怎么回事。但是,演示者却是一头雾水(第二种),很快就感谢了反馈,并继续进行了审查。

“我不会被忽视的!”建筑师尖声尖叫,猛地站起身来,手掌砰地一声砸在桌面上。

当拳头捶桌子时,房间里爆发了,经理们开始想办法遮住他们的屁股,工程师们开始翻阅他们的编码风格手册,包括目录、索引、脚注和参考资料。

演示者表面上没有受到干扰,但感到很恼火,因为他迫切希望完成审查,这样他就可以在斯诺夸尔米进行滑雪之旅。“你说的是类型不匹配?”他随口问道。

建筑师微微一怔,但很快就镇定下来,“显然”,他哼了一声。

演示者将“-1”两个字符替换为“~0”,转身。建筑师仔细检查了更改,然后是屏幕的其余部分,然后查阅了他的笔记,最后又坐了下来。

其余的审查很顺利。

于 2012-06-08T03:21:41.247 回答
24

在二进制补码系统上(并且 Windows 始终是二进制补码),~0等于-1,因此对编译器没有意义。

对读者来说可能有一个意义:~0强调它是一个所有位都设置的值,而-1强调它是一个小于 0 的值 1。

在旁边:

在不是二进制补码的系统上,并假设它SOCKET是无符号类型,通常(SOCKET)(~0). 原因是在这样的系统上,~0不表示值 -1,它是INT_MIN、负零或陷阱表示之一。因此,它不一定会转换为类型SOCKET为所有位为零的值,而是将转换为INT_MAX+20或 goodness-knows-what (可能是所有位设置的值)。

所以通常你应该初始化无符号类型-1以获取所有位设置的值。如果您知道要处理的无符号类型,则可以使用UINT_MAX、 或或类似的。~0UL但这不值得,因为-1适用于所有无符号类型。

于 2012-05-30T13:38:11.330 回答
4

主要是草率。-1 和 ~0 实际上是同一件事。

您可能会争辩说 ~0 是更好的样式,因为套接字是无符号整数,但实际上它对于任何实际目的都没有任何区别。

因为他们使用“#define”而不是“const unsigned”,所以你仍然对陌生事物持开放态度。例如

    unsigned   a = SOCKET_ERROR;
    long long  b = a;
    if (b != SOCKET_ERROR)
        std::cout << "????\n";

可能会给一些人一个惊喜。

于 2012-06-07T16:55:22.293 回答
0

因为 SOCKET 是无符号的,所以不能使用 (-1)。

于 2012-05-30T13:50:08.360 回答
0

INVALID_SOCKET用于返回 a 的函数SOCKET,它是一个指针(很像 a HANDLE)。在 32 位系统上它将是一个 32 位值,而在 64 位系统上它将是一个 64 位值。

当正确转换为等效大小的整数时,它将与-1. 但是不要假设它总是会被正确地投射会更安全。

于 2012-06-04T19:49:12.663 回答
0

每个 (-1) 都是 (~0) 但不是每个 (~0) 都是 (-1)。

于 2014-10-14T11:32:59.297 回答