I am unable to find any reference to the specified behavior of fputc()
when the stream was created with fopen("/some/path", "r")
.
I've searched the C11 Draft n1570 pdf looking for any reference with no luck, the fopen()
function specification talks about passing unknown characters as the mode parameter which is undefined behavior. But it doesn't say anything about subsequent IO on the created stream.
This is the fwrite()
function specification
7.21.8.2 The
fwrite
functionSynopsis
#include <stdio.h> size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream);
Description
- The
fwrite
function writes, from the array pointed to byptr
, up tonmemb
elements whose size is specified bysize
, to the stream pointed to bystream
. For each object, size calls are made to thefputc
function, taking the values (in order) from an array ofunsigned char
exactly overlaying the object. The file position indicator for the stream (if defined) is advanced by the number of characters successfully written. If an error occurs, the resulting value of the file position indicator for the stream is indeterminate.Returns
- The
fwrite
function returns the number of elements successfully written, which will be less thannmemb
only if a write error is encountered. Ifsize
ornmemb
is zero,fwrite
returns zero and the state of the stream remains unchanged.
It takes us to the fputc()
function, so
7.21.7.3 The
fputc
functionSynopsis
#include <stdio.h> int fputc(int c, FILE *stream);
Description
- The
fputc
function writes the character specified byc
(converted to anunsigned char
) to the output stream pointed to bystream
, at the position indicated by the associated file position indicator for the stream (if defined), and advances the indicator appropriately. If the file cannot support positioning requests, or if the stream was opened with append mode, the character is appended to the output stream.Returns
- The
fputc
function returns the character written. If a write error occurs, the error indicator for the stream is set andfputc
returnsEOF
.
As you can see, there is no explanation of the situation I am concerned about.
Description. The fputc() function converts c to an unsigned char and then writes c to the output stream at the current position and advances the file position appropriately. If the stream is opened with one of the append modes, the character is appended to the end of the stream.
The syntax of the fputc() function is as follows: Syntax: int fputc(int ch, FILE *fp); The fputc() function is used to write a single character specified by the first argument to a text file pointed by the fp pointer. After writing a character to the text file, it increments the internal position pointer.
This is undefined behavior, the standard does not define the behavior if it is not an output stream. This is from section 4
Conformance which says (emphasis mine):
If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or runtime constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’.
Now of course this does not prevent the implementation from further defining the behavior and we can see that for POSIX fputc indicates this error through EBADF
:
[EBADF]
[CX] [Option Start] The file descriptor underlying stream is not a valid file descriptor open for writing.
Note CX
denotes an extension to the C standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With