考虑代码片段:
int main(void)
{
int i = 42;
int *p = &i;
++p; // Is this pointer evaluation undefined?
*p = 5; // How about this?
return 0;
}
++p
中指针的评估是不正确的?
C标准(C11,6.5.6)允许评估指向数组对象的一个结尾的指针?这是否也适用于非数组对象?
答案 0 :(得分:9)
没有。上述程序中的++p
定义明确。但*p=5;
会导致undefined behaviour。
C标准声明
C11草案,6.5.6加法运算符,第7页
出于这些运算符的目的,指向对象的指针 不是数组的元素与指向第一个元素的指针的行为相同 长度为1的数组的元素,其对象的类型为 元素类型。
这允许我们在对象int i
和6.5.6执行指针算术时将int i[1];
视为i
,p8如下:
[..]如果指针操作数和结果都指向元素 相同的数组对象,或者超过数组最后一个元素的数组 对象,评估不得产生溢出;否则, 行为未定义。如果结果指向最后一个元素 对于数组对象,它不应该用作一元
*
的操作数 被评估的运算符。
因此&i+1
的评估在C中是明确定义的,i
是否是一个对象数组。但是,取消引用它是未定义的:
int i = 9;
int *p = &i + 1; // Only pointer evaluation done here. Well-defined.
int x = *(p-1); // well defined. p-1 is should be equal to &i as required by 6.5.6, p8
*p = 42; // ill-formed.
int arr[5];
int *q = arr+5; // well-defined. Evaluating one past the end of an array.
*q = 42; //This is undefined.
但是,这仅适用于数组的一个结尾。例如,以下第二个增量是未定义的:
int i = 9;
int *p = &i;
++p; // This is OK. Evaluation is allowed.
*p = 5; // This is undefined. Not allowed to de-reference the pointer one past the end.
++p; // This is undefined. `p` now points to two past the end of the object after increment.
*p = 5; // This is undefined.