使用读取模式打开的流的fputc()行为

Iha*_*imi 9 c fopen stdio undefined-behavior language-lawyer

我无法找到任何对使用fputc()时创建流的指定行为的引用fopen("/some/path", "r").

我搜索了C11草案n1570 pdf寻找没有运气的任何参考,fopen()功能规范谈到将未知字符作为模式参数传递,这是未定义的行为.但它没有说明创建的流上的后续IO.

这是fwrite()功能规范

7.21.8.2 fwrite功能

概要

  1. #include <stdio.h>
    size_t fwrite(const void * restrict ptr,
        size_t size, size_t nmemb, FILE * restrict stream);
    
    Run Code Online (Sandbox Code Playgroud)

描述

  1. fwrite函数写入,从阵列所指向的ptr,最多nmemb,其大小由指定的元素size,到流指向stream.对于每个对象,对fputc函数进行大小调用,从unsigned char完全覆盖对象的数组中获取值(按顺序).流的文件位置指示符(如果已定义)按成功写入的字符数提前.如果发生错误,则流的文件位置指示符的结果值是不确定的.

返回

  1. fwrite函数返回成功写入的元素数,这将少于nmemb仅在遇到写入错误时.如果为sizenmemb为零,则fwrite返回零,并且流的状态保持不变.

这需要我们的fputc()功能,所以

7.21.7.3 fputc功能

概要

  1. #include <stdio.h>
    int fputc(int c, FILE *stream);
    
    Run Code Online (Sandbox Code Playgroud)

描述

  1. fputc函数将由c(转换为a unsigned char)指定的字符写入由流stream的相关文件位置指示符(如果已定义)指示的位置处指向的输出流,并适当地前进指示符.如果文件不支持定位请求,或者使用追加模式打开流,则该字符将附加到输出流.

返回

  1. fputc函数返回写入的字符.如果发生写入错误,则设置流的错误指示符并fputc返回EOF.

如您所见,对我所关注的情况没有任何解释.

Sha*_*our 5

这是未定义的行为,如果标准不是输出流,则标准不会定义行为.这是来自4Conformance的部分(强调我的):

如果违反了约束或运行时约束之外出现的''shall''或''shall not''要求,则行为未定义.未定义的行为在本国际标准中以"未定义的行为" 或"省略行为的任何明确定义"的方式表示.这三者之间的重点没有区别; 他们都描述了"未定义的行为".

当然,这并不妨碍实现进一步定义行为,我们可以看到对于POSIX fputc 通过EBADF以下方式指示此错误:

[EBADF]

[CX] [Option Start]文件描述符基础流不是用于写入的有效文件描述符.

注意CX表示C标准的扩展.