检查读写系统调用的 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 的评论中回答了样式问题。
效率也更好,特别是如果编译器更积极地优化代码
首先我会考虑性能,使用 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”……只是因为它能捕获所有内容。
我有兴趣从 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 的评论中回答了样式问题。
效率也更好,特别是如果编译器更积极地优化代码
首先我会考虑性能,使用 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”……只是因为它能捕获所有内容。