是否正在评估指向超出对象存储的指针未定义?

时间:2015-07-20 08:48:17

标签: c pointers c11

考虑代码片段:

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)允许评估指向数组对象的一个​​结尾的指针?这是否也适用于非数组对象?

1 个答案:

答案 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.