P__*_*J__ -2 c null pointers pointer-arithmetic language-lawyer
是((char *)NULL - (char *)NULL)UB吗?
海事组织的答案在这里不是微不足道的。有什么想法吗?
Godbolt 实验链接https://godbolt.org/z/zgVGk9
我不是在问添加一些空指针的东西(就像在提议的欺骗中一样),而只是关于一种特殊情况。
该表达式具有未定义的行为。
(此问题已作为此问题的副本关闭,但仅讨论指针+整数算术,而不是此问题所询问的指针-指针算术。如果存在特定的现有问题,请随时将问题关闭为副本询问指针减法。)
N1570是 2011 ISO C 标准的草案。第 6.5.6 节第 9 段,讨论减法,说:
两个指针相减时,都指向同一个数组对象的元素,或者指向数组对象最后一个元素后的一个;结果是两个数组元素的下标之差。
(单个非数组对象被视为 1 元素数组的元素,但这不适用于此处。)
表达式产生的指针(char*)NULL不指向数组对象的元素,也不指向任何其他对象(6.3.2.3 第 3 段),因此((char *)NULL - (char *)NULL)违反了should。违反约束或运行时约束之外的应会导致具有未定义的行为(第 4 节第 2 段)。
简短的回答是肯定的,行为是未定义的:
C17 J.2 未定义的行为(信息性)
在以下情况下,该行为是未定义的:
- 不指向或超出同一数组对象的指针将被减去 (6.5.6)。
长(规范)答案是这样的:
C17 6.5.6 加法运算符
...
当两个指针相减时,两个指针都应指向同一个数组对象的元素,或者指向数组对象最后一个元素之后的一个;结果是两个数组元素的下标之差。结果的大小是实现定义的,其类型(有符号整数类型)
ptrdiff_t在<stddef.h>标头中定义。如果结果无法用该类型的对象表示,则行为未定义。换句话说,如果表达式P和Q分别指向数组对象的第i-th 和j-th 元素,则表达式(P)-(Q)具有该值i - j,前提是该值适合类型 的对象ptrdiff_t。此外,如果表达式P指向数组对象的一个元素或数组对象最后一个元素之后的一个元素,并且表达式Q指向同一数组对象的最后一个元素,则表达式((Q)+1)-(P)的值与((Q)-(P))+1和 相同-((P)-((Q)+1)),并且如果表达式P指向数组对象的最后一个元素之后,则其值为零,即使表达式(Q)+1不指向数组对象的元素。
由于(char *)NULL不指向数组,因此该表达式具有未定义的行为,但正如您在各种编译器上进行的测试一样,您很可能会获得在编译时确定的(char *)NULL - (char *)NULL值。0C 标准不保证这一点,但需要不正当的编译器才能产生其他任何东西。
| 归档时间: |
|
| 查看次数: |
216 次 |
| 最近记录: |