此C ++功能的名称是什么?


82

我在编写一些C ++代码,但错误地省略了函数的名称WSASocket。但是,我的编译器没有引发错误,SOCKET而是将my与整数值1而不是有效的套接字相关联。

有问题的代码应该看起来像这样:

this->listener = WSASocket(address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);

但是,它看起来像这样:

this->listener = (address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);

来自其他语言,这看起来可能是某种匿名类型。如果功能确实是功能,名称是什么?

目的是什么?

当您不知道从哪里开始时,很难进行搜索。


3
+1,对于发布测验来说是一个很好的问题(对于喜欢雇用擅长脑筋急转弯的人的公司,则是一个令人震惊的采访问题)。
Bathsheba 2014年

8
链接到有关逗号运算符的Wikipedia文章。FWIW的常见用途之一是在for循环中获得两个副作用* , ala (int i = 0,j = 0; i <10; ++ i,
Tony Delroy

1
@ MichaelJ.Gray从技术上讲您错了。它不会覆盖行为。想象一下:i=0;j=0;x=i++,j=6;x和j分别是6和i都将是1。如果i ++的行为将被覆盖,它将保持为0。但是每个语句都会被调用,并且在到达,所有扩展名之后,所有的扩展都将被丢弃,而下一个伪序列点将被调用。因此,第一个=只是在最后,一个之后分配零件,但是每个点都被调用。无论如何:我不明白为什么您的编译器不会在重新定义函数声明时警告您,而是将您的代码更改为不同的行为
dhein 2014年

5
如果您使用适当的编译器并打开警告,则它会警告此类不可靠的代码,例如,gccg++带有以下-Wall选项:warning: left-hand operand of comma expression has no effect [-Wunused-value]
Sam Watkins 2014年

3
因此,我认为该问题的最佳答案是“始终启用警告”-然后编译器本身将说明存在错误并告诉您您做了什么。这个答案还将为您解决许多其他问题。
山姆·沃特金斯2014年

Answers:


151

逗号运算符†评估左侧,舍弃其值,结果产生右侧。WSA_FLAG_OVERLAPPED为1,这是表达式的结果;所有其他值都将被丢弃。永远不会创建套接字。


†除非过载。是的,它可能会超载。不,您不应该超载。立即离开键盘!


9
+ 1,boost spirit非常有效地使逗号运算符超载,但这是该规则的一个非常孤独的例外:不要这样做
Bathsheba 2014年

2
@Bathsheba Boost.Assign也重载了逗号运算符,但是自C ++ 11起,谁使用它?
rubenvb 2014年

39
但是,您确实对强大的逗号有多可怕有最好的解释。毫无饶恕且充满嘲讽,它困扰了我的代码几分钟,同时盯着我看,不为它的行为感到羞耻。
Michael J. Gray


1
@ R.MartinhoFernandes-本征也非常有效地使逗号运算符重载。有关一些示例用法,请参见此SE问题
David Hammen 2014年

22

逗号操作符是使你的代码感。

您正在有效地设置this->listener = WSA_FLAG_OVERLAPPED;恰好在语法上有效的设置。


3
不仅在语法上有效,而且由于Windows API的类型不安全,因此它也是有效的转换。
MSalters 2014年

5
@MSalters并不是说POSIX在这方面要好得多
chbaker0 2014年

1
这就是为什么可以使用单个参数调用的构造函数应该是显式的,然后会发生编译器错误,并且开发人员将有机会重新审视这个奇怪的构造。
Matthieu M.

@MSalters嗯,SOCKET是的typedef unsigned int,并且WSA_FLAG_OVERLAPPEDint文字。如果SOCKET成为的同义词int,它甚至不会成为转换
Joker_vD 2014年

1
@Joker_vD:确实。如果他们将其设为typedef struct __socket*,我们的bug将会更少。但是那里有太多的代码,“知道”SOCKET是必不可少的。
MSalters 2014年

21

编译器依次在括号内评估每个序列点,结果是表达式WSA_FLAG_OVERLAPPED中的最终表达式。

逗号运算符,是C ++中的一个序列点。逗号左边的表达式在右边的表达式之前已被完全求值。结果始终是右边的值。当您获得形式为(x1,x2,x3,...,xn)的表达式时,表达式的结果始终为xn


在此处添加说明之后,这更有意义。起初我不太了解顺序点问题的相关性。
Michael J. Gray
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.