Last update: 09 November,1998
98 #007
_____________________________________________________________________________
Topic: fwrite when size=0
Relevant Sections: fwrite
Spec: XSH5
------------------------------------------------------------------------
Defect Report concerning (volume of the Single UNIX Specification):
System Interfaces & Headers Issue 5 (XSH5) [UNIX 98]
------------------------------------------------------------------------
Qualifier (e.g. error, omission, clarification required):
1
Error=1 , Omission=2, Clarification=3
------------------------------------------------------------------------
References in document (e.g. page, clause, figure, and/or table
numbers or URL if applicable):
http://www.opengroup.org/onlinepubs/7908799/xsh/fwrite.html
------------------------------------------------------------------------
Nature of defect (complete, concise explanation of the perceived
problem):
The return value for the case size=0, nitems>0 (e.g. fwrite(buf, 0, 1,
stream)) contradicts the ISO C specification, which states:
[#3] The fwrite function returns the number of elements
successfully written, which will be less than nmemb only if
a write error is encountered.
Since no write error can occur if size equals 0, the ISO C
specification demands that fwrite(buf, 0, n, stream) returns n for any
n>=0. The above URL of the Single Unix specification clearly indicates
that 0 should be returned.
The same contradiction appears in Single Unix's fread() specification,
even more clearly, because like the ISO C standard it states:
fread() returns the number of
members successfully read which is less than nitems only if a read
error or end-of-file is encountered.
------------------------------------------------------------------------
Solution proposed by the submitter (optional):
A possible solution would be to adopt the ISO C wording for the return
values of fwrite() and fread(), and omitting the special case `If size
or nitems is 0 ...'.
------------------------------------------------------------------------
Proposed resolution.
The C standard is inconsistent regarding fread() and fwrite() when
size==0. In fread(), there's an explicit sentence which specifies
that if either size or nmemb is 0 that the return value is zero, hence
the Single UNIX Specification fread() interface is aligned . The
are of contention is the lack of an equivalent sentence in fwrite().
(a comment has been sent to the c9x committee).
All known UNIX implementations return 0 for both functions when
either size or nmemb is zero because the they essentially turn into
calls to read() or write() of size*nmemb bytes. The C standard was
supposed to codify existing practice, and this looks like an ommision.
The current additional wording in the Single UNIX Specification is
justified as follows:
First of all, the C standard does not acknowledge the possibility
for a zero-sized object. Nowhere does it require an implementation to
accept such.
Arrays cannot have zero length. Structures must have at least one
real (not :0) member. malloc(0) has two different behaviors. This
was a deliberate decision by the C committee.
Thus, passing size==0 to fwrite() is outside the bounds of the
standard, since the "Use of library functions" clause explicitly
says that "If an argument to a function has an invalid value (such
as a value outside the domain of the function, or a pointer outside
the address space of the program, or a null pointer), the behavior
is undefined."
For fread(), since the standard specifies a behavior when size==0,
that's okay, but for fwrite(), there is no requirement that the
function do anything reasonable at all. The additional text in
the Single UNIX Specification of fwrite() are providing a specification
where the C standard had unbounded behavior.
Forwarded to Base group: Nov 9 1998