在 C 语言中据说当指针引用同一个数组或超出该数组末尾的一个元素时,算术和比较就得到了明确的定义。那么数组第一个元素之前的一个呢?只要我不取消引用它就可以吗?
Given
int a[10], *p;
p = a;
(1)这样写是否合法--p
?
(2)这样写是否合法p-1
在一个表达式中?
(3)如果(2)可以,我可以断言p-1 < a
?
对此有一些实际的担忧。考虑一个reverse()
反转以结尾的 C 字符串的函数'\0'
.
#include <stdio.h>
void reverse(char *p)
{
char *b, t;
b = p;
while (*p != '\0')
p++;
if (p == b) /* Do I really need */
return; /* these two lines? */
for (p--; b < p; b++, p--)
t = *b, *b = *p, *p = t;
}
int main(void)
{
char a[] = "Hello";
reverse(a);
printf("%s\n", a);
return 0;
}
我真的需要检查代码吗?
请从语言律师/实践的角度分享您的想法,以及您将如何应对这种情况。
(1)--p这样写合法吗?
正如 C 语法所允许的那样,它是“合法的”,但它会调用未定义的行为。为了查找标准中的相关部分,--p
相当于p = p - 1
(除了p
仅评估一次)。然后:
C17 6.5.6/8
如果两个指针
操作数和结果指向同一个数组对象的元素,或者指向最后一个元素
数组对象的元素,求值不得产生溢出;否则,行为是未定义的。
The 评估调用未定义的行为,这意味着您是否取消引用指针并不重要 - 您已经调用了未定义的行为。
此外:
C17 6.5.6/9:
当两个指针相减时,两个指针都应指向同一个数组对象的元素,或者指向数组对象最后一个元素之后的一个;
如果您的代码违反了 ISO 标准中的“应”,则会调用未定义的行为。
(2) 表达式中写p-1是否合法?
与 (1) 相同,未定义的行为。
至于这在实践中如何导致问题的示例:想象一下数组被放置在有效内存页的最开始处。当您在该页面之外递减时,可能会出现硬件异常或指针陷阱表示。对于微控制器来说,这并不是完全不可能的情况,特别是当它们使用分段内存映射时。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)