代码之家  ›  专栏  ›  技术社区  ›  P.P

评估指向对象存储之外的指针是否未定义?

  •  2
  • P.P  · 技术社区  · 9 年前

    考虑代码片段:

    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 回复  |  直到 9 年前
        1
  •  9
  •   P.P    9 年前

    ++p 在上面的程序中是定义明确的。但是 *p=5; 导致 undefined behaviour .

    C标准规定

    C11草案,6.5.6加法运算符,p7

    对于这些运算符 数组中的元素与指向第一个元素的指针的行为不同 长度为1的数组的元素,对象的类型为 元素类型。

    这允许我们考虑 int i int i[1]; 对对象执行指针运算时 i 和6.5.6,p8如下:

    [..]如果指针操作数和结果都指向 相同的数组对象,或数组最后一个元素之后的对象 对象,评估不应产生溢出;否则 行为未定义。如果结果指向最后一个元素 数组对象的,它不能用作一元运算的操作数 * 运算符。

    因此 &i+1 无论是否在C中定义 是一个对象数组。但是,取消引用它是未定义的:

    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.