I'm trying to use the c library function fputc from stdio.h
I'm assuming it should work according to the spec at https://linux.die.net/man/3/fputc
Specifically, the parts that are of interest are:
- fputc() writes the character c, cast to an unsigned char, to stream.
- fputc(), putc() and putchar() return the character written as an unsigned char cast to an int or EOF on error.
Based on this information, I assume that if fputc successfully writes the character to the stream provided, I should receive a return value equal to the character written, and if it fails to write to the stream, I should get the value of EOF.
Here is my code:
// COMPILE
// gcc -Wall -Wextra -Werror -O3 -s ./fputc.c -o ./fputc-test
// RUN
// ./fputc-test
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void print_error_exit();
int main() {
FILE * fp;
// ensure file exists
if((fp = fopen("file", "w")) == NULL) print_error_exit();
// close stream
if(fclose(fp) == EOF) print_error_exit();
// open file in read-only mode
if((fp = fopen("file", "r")) == NULL) print_error_exit();
// close stream
if(fclose(fp) == EOF) print_error_exit();
printf("EOF is: %d\n", EOF);
// use fputc on a read-only closed stream (should return error, right?)
printf("fputc returned: %d\n", fputc(97, fp)); // 97 is ascii for 'a'
// expected:
// prints EOF (probably -1)
// actual:
// prints 97 on linux with both gcc and clang (multiple versions tested)
// prints -1 on windows with mingw-gcc
return EXIT_SUCCESS;
}
void print_error_exit() {
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
I have tested the code on Ubuntu 20, Debian 9, Windows 10, using gcc 8.1.0, gcc 8.3.0, gcc 9.3.0, and clang 7.0.1. On windows, I've used mingw.
The only trend I found is that fputc returns what I would expect it to on windows, and does not return what I expect it to on linux.
Which one of the following is correct?
- There is a bug in my code (if there is, explain why and post fixed code please)
- I did not understand the spec correctly (if so, please explain it better)
- There is a bug in both gcc and clang when compiled for linux (where to report this?)
- There is a bug with linux (some distros or all) (where to report this?)
Please help me understand this. Why does fputc not return an error code (EOF) when I try to use it on a closed stream, let alone, a stream that was opened only for reading?
where in the spec
Note that the amazing and great linux man-pages project is, well, great and amazing, but it's not a "specification", it's rather "documentation". (and note that linux.die.net are archival pages, prefer man7 pages, they are more up-to-date). The specification is C standard, and it's typical to use free draft of the standard. – KamilCuk