приводит ли уменьшение указателя NULL к неопределенному поведению? - PullRequest
0 голосов
/ 21 июня 2019

Уменьшение NULL-указателя на моей машине все еще дает NULL-указатель, интересно, правильно ли это определено.

char *p = NULL;
--p;

Ответы [ 2 ]

6 голосов
/ 21 июня 2019

Да, поведение не определено.

--p эквивалентно p = p - 1 (за исключением того, что p оценивается только один раз, что в данном случае не имеет значения).

N1570 6.5.6, пункт 8, в котором обсуждаются аддитивные операторы, говорит:

Когда выражение с целочисленным типом добавляется или вычитается из указателя результат имеет тип операнда указателя. Если операнд указателя указывает на элемент объекта массива и массив достаточно велик, результат указывает на смещение элемента от исходный элемент такой, что разница индексов результирующие и исходные элементы массива равны целочисленному выражению.
[...]
Если и операнд указателя, и результат указывают на элементы одного и того же объекта массива, или один за последним элементом массива объект, оценка не должна производить переполнение; в противном случае поведение не определено.

Поскольку значение вашего указателя p не указывает на элемент объекта массива или один элемент после последнего элемента объекта массива, поведение p - 1 не определено.

(Кстати, я был бы удивлен, если бы ваш код стал причиной того, что p стал нулевым указателем - хотя, поскольку поведение не определено, язык, безусловно, это позволяет. Я могу представить оптимизирующий компилятор, игнорирующий --p;, потому что он знает, что его поведение не определено, но я сам этого не видел. Откуда вы знаете, p равно нулю?)

0 голосов
/ 21 июня 2019

Насколько я вижу с GCC, он не генерирует нулевой указатель. Уменьшение - это просто вычитание числа. При недостаточном количестве число просто оборачивается. Вы можете увидеть это здесь.

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

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

Выход

0
ffffffffffffffff

https://wandbox.org/permlink/gNzc38RWGSBi9tS3

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...