不兼容的printf格式说明符问题

5
我刚刚在查看printf的手册时突然想到了一个问题。我想知道是否有任何“语言律师”可以回答一个相对简单的问题:-P。
因此,'t'修改符被定义为:
随后的整数转换对应于ptrdiff_t参数。
那么如果将其与无符号整数转换组合使用,会发生什么?显然,o、u、x和X都意味着要解释为无符号值,而d和i是有符号的。
同样地,除了ptrdiff_t之外,所有修改符(int/unsigned int、size_t/ssize_t等)都有有符号/无符号版本。
实际上,由于无符号类型的版本占用与有符号版本相同的空间,因此不会发生任何错误。因此,从堆栈中弹出了正确的字节数。
因此,除了“INT_MIN”之外的所有测试值都打印出了预期值(假设sizeof(int) == sizeof(ptrdiff_t))。
printf("%tu %td\n", INT_MIN, INT_MIN);

打印

2147483648 -2147483648

在32位系统上,标准对此有何看法?我觉得答案可能是“未定义行为”。但我想问一下;)


这与C++有关系吗(至少在C++0x之前)?printf()等函数是否会在C++0x中更改以符合C99?我认为你应该删除C++标签。 - David Thornley
ptrdiff_t 在 c++ 的 cstddef 中被定义。printf 在 c++ 中显然也存在。我不知道 c++0x 是否对 printf 进行了任何更改。 - Evan Teran
嗯,似乎 C++ 可能没有 C99 中的 't' 修饰符。好吧。 - Evan Teran
1个回答

3

这里没有什么问题。您编写的代码是合法的。

以下是一些事实,说明为什么:

  • 所有有符号整数类型都有无符号对应类型,大小/对齐要求相同
  • ptrdiff_t 按照标准规定必须是有符号整数类型。因此,它有一个无符号的双胞胎。(事实上,类似的逻辑也适用于 size_t - ssize_t 不是 C,但是 POSIX)
  • t 长度修饰符必须与 diouxX 类型一起使用

ptrdiff_t的有效无符号等价是什么? - user83255
它没有特定的名称 - 只能说如果ptrdiff_t是“long long”,那么它的无符号对应项就是“unsigned long long”等。 - jpalecek
你忽略的重要事实是,在整数类型的有符号和无符号变体中,当值适合时,它具有相同的表示形式,并且标准明确允许在这种情况下传递“错误”的参数类型(这仅适用于没有原型和可变参数函数)。就我所知,当格式说明符期望无符号类型时,传递负的ptrdiff_t值将导致未定义行为。 - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接