[英]Rationale for system calls that allow request of size_t but result of only ssize_t?
考慮:
ssize_t write(int fd, const void *buf, size_t count);
必須對結果進行簽名以說明錯誤為 -1 等,因此為 ssize_t。 但是,當請求超過 ssize_t 的結果未定義時,為什么還要允許請求為無符號數量(兩倍大)?
由於不檢查計數參數的符號,kernel 中是否有顯着優化? 或者是其他東西?
根據ssize_t write(int fildes, const void *buf, size_t nbyte)
的文檔
如果 nbyte 的值大於 {SSIZE_MAX},則結果是實現定義的。
因此,每個特定的實現可能會以不同的方式處理這種情況。 如果某些實現只是設置EFBIG
,我不會感到驚訝。
至於基本原理,也許size_t
在語義上只是表示緩沖區大小的最佳類型? 它指出這個參數是一個非負的大小,沒有別的。
我認為這很好,因為size_t
是sizeof
運算符返回的值的類型,這允許這樣的調用:
char buffer[1 << 20];
ssize_t wrote;
wrote = write(fd, buffer, sizeof buffer);
如果 function 采用簽名版本,則需要演員表。 此外,正如其他人指出的那樣,像這樣的語義函數不能接受負值,因此接受它們沒有多大意義。
通過使參數無符號,它消除了 function 檢查無意義的否定請求的需要。
write
只能從一個連續的unsigned char
數組寫入,它不能大於PTRDIFF_MAX
,它(在所有現實世界的 POSIX 系統上,也許這也是 POSIX 所要求的......?)等於SIZE_MAX/2
。 因此,傳遞一個如果被解釋為有符號值則為負的值首先是一個編程錯誤——傳遞的大小與緩沖區中的可用空間不符。
理論上readv
和writev
可以通過在數組中多次重復相同的iov
緩沖區來執行大於SIZE_MAX/2
的 IO 操作,但如果我沒記錯的話,如果總大小大於SSIZE_MAX
,它們被指定為失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.