在printf文档中,“ signed`size_t`”是什么意思?

时间:2019-12-20 17:20:05

标签: c

我在浏览有关cppreference(https://en.cppreference.com/w/c/io/fprintf)的printf文档时,发现使用z修饰符和d说明符时,该类型被列为“有符号{{ 1}}”。这让我感到好奇,所以我调查了为什么不使用size_t只是为了发现ssize_t是POSIX类型而不是标准类型。那么,这是什么类型的期望呢?寻找签名的ssize_t类型时,我找不到ssize_t以外的任何内容。

编辑:为澄清起见,我问我将使用哪种数据类型来表示签名的size_t

2 个答案:

答案 0 :(得分:4)

“符号size_t”的确切类型是实现定义的,并且是AFAIK,没有标准的方法来获取类型。因此,我看不到可移植地使用%zd的方法。在大多数平台上,ptrdiff_t应该是size_t的签名版本,但这不能保证。实际上,t有一个ptrdiff_t格式修饰符,它也可以与u这样的%tu修饰符一起使用,表示“无符号ptrdiff_t”。我认为这些组合仅出于完整性考虑,没有实际用途。

答案 1 :(得分:4)

术语“签名size_t”是非正式使用的,并且未出现在语言标准中。实际上,如果您尝试在C代码中使用它,那将是语法错误。

C标准规定z长度修饰符:

  

指定以下 d i o { {1}} u x 转换说明符   适用于 X 或相应的带符号整数类型参数;   或以下 size_t 转换说明符适用于指向   与 n 参数相对应的带符号整数类型。

没有可移植的方法来确定相应的带符号整数类型是什么。即使是特定于POSIX的size_t类型(在ssize_t中定义)也未指定为与<sys/types.h>对应的带符号类型。就像chux在评论中指出的那样,在某些实现中,size_tssize_t宽是有意义的,因此它可以表示直到size_t的所有值(当然,加上,负值)。

实际上,SIZE_MAX通常是预定义的无符号整数类型size_tunsigned intunsigned long intunsigned long long int中的一种的typedef然后分别需要类型为%zdintlong int的参数。 long long int也可能是根据某些扩展整数类型定义的。

我的猜测是,该标准的作者根本不想花费精力指定size_t长度修饰符仅适用于带符号的类型。这样做会增加复杂性,却没有真正的好处。如果您使用的是符合POSIX的实现,则可以可能使用z来打印类型为%zd的值。

ssize_t并没有可移植的用途,但是将其放在%zd中是无害的,而且可能比不在那里使用容易。