'print'在printf函数返回时意味着什么?

时间:2015-02-27 03:00:49

标签: c language-lawyer

我对标准C库中printf的返回值和缓冲流的解释感到困惑。

C99:TC3 Standard中,7.19.6.3 / p3定义printf函数成功返回非负“字符数传输”。 此外,7.19.3 / p3描述了“传输到主机环境或从主机环境传输”的完全/线路缓冲流的行为,而p7表示stdout可以是完全缓冲的流。

引用第7.19.3节,重点强调:

  

7.19.3档案

     

3当流 unbuffered 时,字符应尽快从源或目的地出现。否则,字符可以作为块累积并传输到主机环境或从主机环境传输。当流完全缓冲时,当填充缓冲区时,字符应作为块强制作为块传输到主机环境。   当流行缓冲时,当遇到换行符时,字符将作为块以传输到主机环境 。此外,当填充缓冲区,在无缓冲流上请求输入时,或者在需要使用缓冲流的行缓冲流上请求输入时,字符意图作为块传输到主机环境。从主机环境传输字符。对这些特性的支持是实现定义的,可能会受到setbufsetvbuf函数的影响。

     

7 [...]最初打开时,标准错误流未完全缓冲;当且仅当可以确定流不参考交互设备时,标准输入和标准输出流是完全缓冲的

这些定义导致以下行为是合法的。 但这是违反直觉和不可接受的结果(至少对我而言)。

#include <stdio.h>
#include <assert.h>

// PRECONDITION: `stdout` is fully buffered
int main()
{
   int n = printf("abc");  // "abc" is accumulated, and no transmission.
   assert(n == 0);         // so, return value can be equal to 0 ??
}

我的解释错在哪里? 或者它只是“实现定义”行为中的一种?

2 个答案:

答案 0 :(得分:2)

printffprintf的返回值是传输到流的字节数 - 它是主机环境中的对象 - 而不是最终目标。这些字节何时以及如何通过流传输到文件或设备(“从主机环境传输”)是无关紧要的。缓冲不会影响流如何从程序接受字节;只是在它持有它们之前,直到将它们发送到相关文件或设备上为止。

答案 1 :(得分:1)

传输”一词意味着字节穿过某个接口。我认为7.19.6.3引用的接口是printf和设备驱动程序之间的接口,而7.19.3引用的接口是设备驱动程序的输出。

此外,我认为你提出的解释会使printf的返回值变得任意且反复无常。

因此,我得出结论,示例代码中的printf将始终返回3.