下标运算符中不会发生无符号下溢,为什么?

tox*_*xic -3 c++ integer-overflow

我一直认为下一个例子是未定义的行为(访问数组越界):

int main()
{
    int* a= new int[3];
    a[0] = 100;
    a++;
    
    unsigned long index = 0;
    
    printf("%d\n", a[-1]);
    printf("%d\n", a[index - 1]);
    printf("%ul\n", index - 1);
}
Run Code Online (Sandbox Code Playgroud)

然而,这个输出很好:

100
100
4294967295l
Run Code Online (Sandbox Code Playgroud)

为什么下标运算符不会发生下溢?

Cal*_*eth 5

为什么下标运算符不会发生下溢?

printf("%d\n", a[-1]);已定义行为。指针算术适用于任何整型,因此该signed int-1会添加到a,从而对已初始化的元素进行界内访问。

printf("%d\n", a[index - 1]);有未定义的行为。index - 1是一个混合秩积分表达式,并且比unsigned long具有更大的1int,因此它是一个无符号表达式,相当于std::numeric_limits<unsigned long>::max()。添加它a是超出范围的,因此是未定义的行为。由于该标准对观察到的行为没有提出任何要求,因此打印 100 是符合要求的。

printf("%ul\n", index - 1);有未定义的行为。lu是 的正确格式说明符unsigned long

  1. 同等等级也会导致转换为无符号,因此需要有unsigned short定义的行为。