After RTFM, it is now somewhat unclear to me what I can really infer from the return value of fread()/fwrite() if the returned value is less than the number of requested elements.
Consider at first
nhave = fread(dst, 1, nwant, fp);
From the C17 standard (7.21.8.1/3):
The fread function returns the number of elements successfully read which may be less than nwant if a read error or end-of-file is encountered.
Hence, if nhave < nwant upon return, there could have been a read error or eof (but there could be other reasons as well). Since it's if and not only if, one cannot conclude feof(fp) if !ferror(fp)in this case. If !ferror(fp), it could still have been a successful read (of nhave bytes) according to the standard.
MSDN and cppreference.com have the same wording.
But then POSIX.1-2017:
Upon successful completion, fread() shall return the number of elements successfully read which is less than nwant only if a read error or end-of-file is encountered.
Hence, if nhave < nwant upon return, there must have been a read error or eof (there cannot be other reasons). Thus in this case, one can conclude feof(fp) if !ferror(fp). While being different from the specification in the C Standard, this behavior is not flagged as an extension to the C Standard in POSIX.
And from the fread(3) manual page on Linux (a POSIX-conforming platform):
If an error occurs, or the end of the file is reached, the return value is a short item count (or zero).
Formally, this is the reverse (!) statement to that from POSIX.
Now consider fwrite(),
nhave = fwrite(src, 1, nwant, fp);
Let's start with POSIX.1-2017 here:
The fwrite() function shall return the number of elements successfully written, which may be less than nwant if a write error is encountered.
Hence, if nhave < nwant, there could (but need not) have been a write error. One cannot conclude ferror(fp)in this case but need to check.
MSDN and cppreference.com have the same wording.
However, according to the C17 standard (7.21.8.2/3), one can conclude more:
The fwrite function returns the number of elements successfully written, which will be less than nwant only if a write error is encountered.
Hence in this case, nhave < nwant does imply a write error and thus ferror(fp).
This is even more bizarre than in the case of fread() above since POSIX, Windows, and C++ are each supposed to follow the C standard.
So, what's going on here? Just sloppy wording? In particular and from a programmer's point of view:
Can I assume the POSIX wording for the return value of fread() (as given above) also for C/C++/Windows/..., i.e., does nhave < nwant imply a read error (and thus, ferror(fp)) or eof (and hence, feof(fp))?
Can I assume the C wording of the return value of fwrite() (as given above) also for C++/Windows/POSIX/..., i.e., does nhave < nwant imply a write error (and thus, ferror(fp))?
intto be 32 bits is technically an extension of the C standard, but few people would call it that outside a formal mathematical context. - Eric Postpischil