减少NULL指针会导致未定义的行为吗?

时间:2019-06-21 05:13:39

标签: c

在我的机器上递减NULL指针仍然会提供NULL指针,我想知道这是否定义正确。

char *p = NULL;
--p;

2 个答案:

答案 0 :(得分:6)

是的,行为是不确定的。

--p等效于p = p - 1(除了p仅被评估一次,在这种情况下无关紧要)。

N1570 6.5.6第8段,讨论加法运算符,表示:

  

将具有整数类型的表达式添加或减去时   从指针开始,结果具有指针操作数的类型。如果   指针操作数指向数组对象的元素,并且该数组   足够大,结果指向的元素与   原始元素,使得下标的差异   结果数组元素和原始数组元素等于整数表达式。
  [...]
  如果指针操作数和结果都指向元素   相同的数组对象,或者在数组的最后一个元素之后   目标,评估不得产生溢出;否则,   行为是不确定的。

由于指针值p不指向数组对象的元素,也不指向数组对象的最后一个元素,因此p - 1的行为是不确定的。

(顺便说一句,如果您的代码导致p为空指针,我会感到很惊讶-尽管由于行为是不确定的,所以语言肯定允许它。我可以想象一个优化编译器忽略{{1 }},因为它知道其行为是不确定的,但我自己还没有看到。您怎么知道--p;为空?)

答案 1 :(得分:-1)

据我在GCC上看到的,它不会生成空指针。减少就是减去一个数字。随着下溢,数字就回绕了。您可以在这里看到。

import random
roll = random.randint(1, 6) + random.randint(1, 6)
numbers = roll == 1 or roll == 4 or roll == 5 or roll == 6 or roll == 8 or roll == 9 or roll == 10
while True:
    if roll == 7 or roll == 11:
        print('nice')
        break
    elif  roll == 3 or roll == 2 or roll == 12:
        print('crapped out')
        break
    elif numbers:
        print('your number is:', roll, "roll again...")
        break

输出为

#include "stdio.h"
#include <inttypes.h>

int main()
{
    char *p = NULL;
    printf("%zx\n", (uintptr_t)p);    
    --p;
    printf("%zx\n", (uintptr_t)p);
}

https://wandbox.org/permlink/gNzc38RWGSBi9tS3