为什么 snprintf() 采用 size_t 大小限制,但返回 int 打印的字符数?

ein*_*ica 5 c printf size-t

令人尊敬的snprintf()功能...

int snprintf( char *restrict buffer, size_t bufsz, const char *restrict format, ... );
Run Code Online (Sandbox Code Playgroud)
  • 返回它打印的字符数,或者更确切地说,如果没有缓冲区大小限制,它会打印的字符数。
  • 获取缓冲区的大小(以字符/字节为单位)。

缓冲区大小为size_t,但返回类型仅为 an ,这有什么意义int

如果snprintf()应该能够将多个INT_MAX字符打印到缓冲区中,那么它肯定必须返回一个ssize_t或一个size_t(size_t) - 1指示错误,对吧?

如果它不能打印多个INT_MAX字符,为什么是bufszasize_t而不是 anunsigned或 an int?或者 - 至少官方限制其值不大于INT_MAX

Joh*_*ger 1

size_t缓冲区大小为,但返回类型仅为 int有何意义?

官方 C99 基本原理文档没有讨论这些特定的考虑因素,但大概是出于一致性和(单独的)意识形态原因:

  • 所有-family 函数都返回具有基本相同意义的printfan 。这是在发明之前int就已经定义的(对于原始的printffprintfsprintf) 。size_t

  • typesize_t在某种意义上是传达大小和长度的正确类型,因此它被用作C99 中引入的第二个参数(以及snprintf它本身)。vsnprintfsize_t

如果snprintf()应该能够将多个INT_MAX字符打印到缓冲区中,那么它肯定必须返回一个ssize_t或一个size_t(size_t) - 1指示错误,对吧?

这将是一个更内部一致的设计选择,但不是。相反,似乎选择了整个函数族的一致性。请注意,该系列中的所有函数都没有记录其可以输出的字符数限制,并且它们的一般规范意味着没有固有的限制。因此,它们都面临着相同的输出很长的问题。

如果它不能打印多个INT_MAX字符,为什么 bufsz 是 asize_t而不是 anunsigned或 an int?或者 - 至少官方限制其值不大于INT_MAX

除了必须可表示为 的隐式约束之外,对第二个参数的值没有记录的约束size_t。即使在最新版本的标准中也没有。但请注意,也没有任何内容表明类型int不能表示可表示的所有值size_t(尽管在大多数实现中确实不能)。

因此,是的,当通过这些函数输出非常大的数据时,实现将难以按照规范运行,其中“非常大”取决于实现。那么,作为一个实际问题,人们不应该依赖使用它们在一次调用中发出非常大的输出(除非打算忽略返回值)。