由于奇怪的语法,“非套接字上的套接字操作”错误

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 这是我第一次遇到这个问题。 我建议任何通过简洁获得的实用价值(有点好奇你在想什么价值)都会被可读性下降所抵消。如果您必须在一行上暂停或重复一遍以弄清楚它究竟有什么效果,最好将其分解。

以上是关于由于奇怪的语法,“非套接字上的套接字操作”错误的主要内容,如果未能解决你的问题,请参考以下文章

非套接字上的套接字操作

非套接字上的套接字操作,zmq 选项

虽然没有来自客户端的连接操作,但服务器尝试接受连接并因“非套接字上的套接字操作”而失败

C++ winsock 错误

C ++套接字表现得很奇怪[关闭]

MySQL 语法错误?奇怪的错误