检查读写系统调用的 return 值的最佳方法是什么?

What's the best way to check return value of read and write system calls?

我有兴趣从 Linux 上的读取和写入系统调用中找出检查 return 值的最佳方法。根据手册页,例如写:

Upon successful completion, write() and pwrite() shall return the number of bytes actually written to the file associated with fildes. This number shall never be greater than nbyte. Otherwise, -1 shall be returned and errno set to indicate the error.

待读:

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.

这让我想知道:

if (ret < 0) {
    // see strerror
}

if (ret == -1) {
    // see strerror
}

哪条路要走,为什么?根据手册页,在我看来,从功能的角度来看,它们完全相同。这样对吗?我猜的唯一区别是第一个语句应该使用比较器,这需要更多资源。我对这个假设是否正确?请与我分享你的想法。谢谢

IMO 已在 Maxine 的评论中回答了样式问题。

效率也更好,特别是如果编译器更积极地优化代码

https://godbolt.org/z/MrTdqX

首先我会考虑性能,使用 gcc 9.2 (x86-64):

#include <stdio.h>

int main(int argc, char **args, char **env) {
   if (argc < 0) {
       printf("ERROR!");
   }

   return 0;
}

会生成类似

的东西
.LC0:
        .string "ERROR!"
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        mov     DWORD PTR [rbp-4], edi
        mov     QWORD PTR [rbp-16], rsi
        mov     QWORD PTR [rbp-24], rdx
        cmp     DWORD PTR [rbp-4], 0
        jns     .L2
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
.L2:
        mov     eax, 0
        leave
        ret

#include <stdio.h>

int main(int argc, char **args, char **env) {
   if (argc == -1) {
       printf("ERROR!");
   }

   return 0;
}

生成

.LC0:
        .string "ERROR!"
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        mov     DWORD PTR [rbp-4], edi
        mov     QWORD PTR [rbp-16], rsi
        mov     QWORD PTR [rbp-24], rdx
        cmp     DWORD PTR [rbp-4], -1
        jne     .L2
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
.L2:
        mov     eax, 0
        leave
        ret

因此在性能方面没有任何差异。使用此编译器和架构。

其他均为个人意见。我个人会选择“< 0”……只是因为它能捕获所有内容。