【发布时间】:2016-07-18 16:44:28
【问题描述】:
有没有办法在 C11 中从另一个指针中减去一个指针并始终定义结果?
标准规定如果结果不能表示为类型 ptrdiff_t,则行为未定义。
我对依赖静态断言的解决方案持开放态度,这些断言有望在现代通用 32 位或 64 位环境中传递合理的实现。我想避免依赖于任何类型的运行时检查的解决方案。
如果指向的类型的大小大于 1,我可以静态断言 size_t 和 ptrdiff_t 具有相同数量的非填充位。这个部分解决方案依赖于我不确定的两件事,因此对此的任何反馈都将提供部分答案:
在现代通用 32 位或 64 位环境的合理实现中,可以预期 ptrdiff_t 最多比 size_t 少一个值位。
我对标准的理解是正确的,因为定义了两个指向大小大于 1 的对象的指针之间的差异,即使如果将指针强制转换为字符指针,相同的差异也未定义。这种理解似乎与委员会草案中的脚注 106 不一致,但我的理解是脚注不是规范性的。
【问题讨论】:
-
目的是什么?您可以随时将指针指向
uintptr_t和朋友... -
总是做这样的演员很麻烦,但更重要的是,这并不能解决问题。指针表示为 uintptr_t 类型的方式没有定义,因此减去转换版本不会产生明确定义的结果。
-
@EugeneSh。你可以,但价值没有意义。 C 只保证来回转换不会改变值。
-
指针差异本身也不是很有意义。再说一遍。具体是什么问题?
-
唯一的解决办法是将字符数组的大小限制为
SIZE_MAX / 2。这将需要运行时检查,除非每个字符数组的大小在编译时都是已知的。坦率地说,这个问题没有满足您要求的解决方案。
标签: c pointers undefined-behavior c11 pointer-arithmetic