使用了c编程也有十几个年头的,今天居然因为一个运算符优先级的问题调试程序用了1个多小时。
int TransSock(int nReadSock, int nWriteSock)
{
char buf[1500] = {0};
int nread = sizeof(buf);
if (nread = read(nReadSock, buf, nread) < 0) // --> keypoint.
{
if (errno != EINTR)
return 1;
else
return 0;
}
else if (nread == 0)
{
//printf("client is close\n");
return 2;
}
printf("nread=%d\n", nread);
if (WriteFile(nWriteSock, buf, nread) != 0)
{
printf("write message to service error.\n");
return 1;
}
return 0;
}
这个函数是想把readsock读到的内容写入writeSock,但是每次得到的nread都是0.刚开始以为就是没有数据读到。然后我用wireshark抓数据,工具是可以抓到数据有收到的。这个就奇怪了,难道是kernel把数据没有送到上层应用,丢掉了?
调试一度陷入僵局,没法进展了!又把所有的相关的代码检查了一遍还是没有发现问题。初步怀疑应该还是上边这个函数出问题了, 还有我就把这个函数又写了一遍,主要就是把“if (nread = read(nReadSock, buf, 1500) < 0) ”这个语句拆分成了两句:
nread = read(nReadSock, buf, nread);
if (nread < 0)//error
{
...
}
就这样,奇迹发生了,可以读到数据了!!! What is the different?
if (nread = read(nReadSock, buf, nread) < 0) <--?--> if ( (nread = read(nReadSock, buf, nread)) < 0 )
哦,看到了,是运算符的优先级问题。左边的那个句子是先进行“<”的逻辑运算,然后把逻辑运算的结果再赋给nread。因为是可以读到数据的,所以那个‘<’的逻辑运算的结果就是false了。所以我们得到的nread就一直是0.
个人觉得,如果我们不记得运算符的优先级时,记得用括号来限定运算顺序,这样就可以保证代码和我们的期望是一致的了。这个懒偷得太不值了。用文字记录一下。
最后再附上c的运算符顺序: