由于奇怪的语法,“非套接字上的套接字操作”错误
Posted
技术标签:
【中文标题】由于奇怪的语法,“非套接字上的套接字操作”错误【英文标题】:"Socket operation on non-socket" error due to strange syntax 【发布时间】:2010-06-17 09:12:06 【问题描述】:在调用connect
时,我在一些网络代码中遇到了错误Socket operation on non-socket
,并花了很多时间试图找出导致它的原因。我终于发现是下面这行代码导致了这个问题:
if ((sockfd = socket( ai->ai_family, ai->ai_socktype, ai->ai_protocol) < 0))
看到问题了吗?这条线应该是这样的:
if ((sockfd = socket( ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0)
我不明白为什么第一行不正确的行不会产生警告。换一种说法,不应该是一般形式:
if ( foo = bar() < baz ) do_something();
编译器看起来很奇怪,尤其是使用g++ -Wall -Wextra
运行?
如果不是,它至少不应该对 cppcheck 显示为“坏样式”吗?我也在编译过程中运行它?
【问题讨论】:
几乎是我讨厌“赋值-条件”的原因... 我支持你,ereOn。我也讨厌“逗号运算符”——我曾经无意中在两个物理行的加法末尾有一个逗号,我花了一段时间才弄清楚为什么我得到了愚蠢的结果。如果有 #pragmas 或编译器选项来禁用此类 C 习语,这样我们就可以避免此类问题(并获得 OP 想要的错误/警告),那就太好了。 @JTeagle:当然,是的。实际上,OP没有收到警告的原因确实是缺乏运气。看我的回答。 【参考方案1】:实际上,由于双括号(
,您不会收到任何警告。
尝试删除一对,您会收到警告。
#include <iostream>
int foo()
return 2;
int main(int /*argc*/, char** /*argv*/)
int l;
if ((l = foo() < 3)) // Won't generate warning under gcc
if (l = foo() < 3) // will generate a warning "warning: suggest parentheses around assignment used as truth value"
return EXIT_SUCCESS;
为了避免这种烦人的错误/错别字,我避免在同一个语句中分配一个值并对其进行测试。恕我直言,这太容易出错了。
【讨论】:
为什么额外的括号会有所作为? @Robert S. Barnes:我想这是为了防止出现错误,比如写if (i = 5)
而不是if (i == 5)
。如果你真的想做if (i = 5)
,gcc
删除这个警告的方法是用括号括住赋值,从而将它加倍,以表明“这不是错字,这是意思 !”。正如您的问题所示,可能不是一个完美的解决方案!
我认为 cppcheck 会捕获这两种情况,但令人惊讶的是,如果没有额外的 ()
,它甚至无法捕获第二种情况。【参考方案2】:
这就是为什么我尽量不在一个声明中做太多的原因之一。而不是
if ((sockfd = socket( ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0)
为什么不:
sockfd = socket( ai->ai_family, ai->ai_socktype, ai->ai_protocol)
if(sockfd < 0)
【讨论】:
没错。在一个声明中放太多是不好的风格。此外,如果将 if 放在下一行,调试也会容易得多。 虽然我可能同意一般性陈述,“不要在一个陈述中做太多”,但我不知道它是否适用于此。代码简洁有实用价值,而且这种特殊的 C/C++ 习语已经存在了很长时间,并且基本上是标准做法。我已经编程了大约 10 年,IIRC 这是我第一次遇到这个问题。 我建议任何通过简洁获得的实用价值(有点好奇你在想什么价值)都会被可读性下降所抵消。如果您必须在一行上暂停或重复一遍以弄清楚它究竟有什么效果,最好将其分解。以上是关于由于奇怪的语法,“非套接字上的套接字操作”错误的主要内容,如果未能解决你的问题,请参考以下文章