读取(3)“调用的长度大于目标缓冲区的大小”

时间:2022-07-07 21:45:06

With the following code:

用下面的代码:

#define MIN(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); _a < _b ? _a : _b; })
...
size_t const recvBufLength = 50*1024*1024;
char * const recvBuf = malloc(recvBufLength);
...
while ((r = read(sockfd, recvBuf, MIN(recvLength-received, recvBufLength))) > 0) {
    ...
}

I'm getting this error:

我得到这个错误:

/usr/include/x86_64-linux-gnu/bits/unistd.h: In function ‘main’:
/usr/include/x86_64-linux-gnu/bits/unistd.h:39:2: error: call to ‘__read_chk_warn’ declared with attribute warning: read called with bigger length than size of the destination buffer [-Werror]
  return __read_chk (__fd, __buf, __nbytes, __bos0 (__buf));
  ^
lto1: all warnings being treated as errors
lto-wrapper: gcc returned 1 exit status
/usr/bin/ld: lto-wrapper failed
collect2: error: ld returned 1 exit status

If I get rid of the MIN and change the read to read(sockfd, recvBuf, recvBufLength) then it compiles without complaint.

如果我去掉最小值,并将读取改为read(sockfd、recvBuf、recvBufLength),那么它就会毫无怨言地编译。

Is this my mistake, or GCC's, or glibc's?

这是我的错,还是GCC的错,还是glibc的错?

If not the former, then how can I circumvent the flawed length checking?

如果不是前者,那我该如何规避有缺陷的长度检查呢?


Edit:

编辑:

Even expanding the MIN macro to a simple ternary operation still gives the error.

即使将最小宏扩展为简单的三元操作也会产生错误。

read(sockfd, recvBuf, (recvLength-received)<recvBufLength?(recvLength-received):recvBufLength)

This is all in GCC 4.8.2, I'll try other versions shortly.

所有这些都在GCC 4.8.2中,我稍后将尝试其他版本。

1 个解决方案

#1


3  

I think it is because the MIN macro expands as a block and not as an expression (there { } in the macro). I don't think it is allowed in every C standard (see C block becomes expression: ( {int a = 1; int b = 2; a+b;} ) equals 3).

我认为这是因为MIN宏扩展为块而不是表达式(在宏中有{})。我不认为它在每个C标准中都被允许(见C块变成表达式:({int a = 1;int b = 2;a + b;})= 3)。

Maybe try to put the result of MIN in a variable first

可以先把最小值的结果放到一个变量中

val=MIN(recvLength-received, recvBufLength));
while ((r = read(sockfd, recvBuf, val) > 0) {
    ...
    val=MIN(recvLength-received, recvBufLength));
}

Interesting, I just learned something!

有趣的是,我刚学到了一些东西!

#1


3  

I think it is because the MIN macro expands as a block and not as an expression (there { } in the macro). I don't think it is allowed in every C standard (see C block becomes expression: ( {int a = 1; int b = 2; a+b;} ) equals 3).

我认为这是因为MIN宏扩展为块而不是表达式(在宏中有{})。我不认为它在每个C标准中都被允许(见C块变成表达式:({int a = 1;int b = 2;a + b;})= 3)。

Maybe try to put the result of MIN in a variable first

可以先把最小值的结果放到一个变量中

val=MIN(recvLength-received, recvBufLength));
while ((r = read(sockfd, recvBuf, val) > 0) {
    ...
    val=MIN(recvLength-received, recvBufLength));
}

Interesting, I just learned something!

有趣的是,我刚学到了一些东西!