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