Это нулевые указатели или указатели на адрес 0?

Если я напишу

int zero = 0;

void *p1 = (void *)0;
void *p2 = (void *)(int)0;
void *p3 = (void *)(0 /*no-op, but does it affect the next zero?*/, 0);

void *p4 = (void *)zero;    // For reference, this is a pointer to address zero
void *p5 = 0;               // For reference, this is a null pointer
void *p6 = NULL;            // For reference, this is a null pointer
void *p7 = nullptr;         // For reference, this is a null pointer (C++11)

static const int static_zero_1 = 0;       // Is this a literal zero when used?
static const int static_zero_2 = 1 - 1;   // No "literals 0" per se... is it?
void *p8 = (void *)static_zero_1;   // I have seen weird substitution rules...
void *p9 = (void *)static_zero_2;   // do they apply for NULL too?

какой из p1, p2, а также p3 (редактировать: я добавил p8 а также p9) было бы нулевые указатели (Т.е. == NULL, может или не может быть адрес ноль), и какие из них будут указатели с адресом ноль (может или не может быть == NULL)?

Если ответ различается в C и C ++, что в каждом из них?

18

Решение

p1 а также p2 нулевые указатели; p3 определяется реализация,
и может быть что-то еще. (Оператор запятой не может быть частью
постоянное выражение. И отображение непостоянное
целое значение 0 для указателя определяется реализацией.) C является
идентичен C ++ здесь.

p8 а также p9 оба являются нулевыми указателями в C ++, но не в C.

Что касается вашего комментария static_zero_2, здесь нет
требование на любом языке, чтобы присутствовал буквальный ноль,
в любом месте. g ++ определяет NULL как встроенный компилятор __null,
например, и вы можете использовать (1 - 1), или же '\0'или любой другой
константное выражение с оценкой 0.

8

Другие решения

И чтобы завершить ответ Энди с C:

Из стандарта C99:

6.3.2.3. Указатели

1 Указатель на void может быть преобразован в или из указателя на любой незавершенный объект
тип. Указатель на любой неполный или тип объекта может быть преобразован в указатель на void
и обратно снова; результат должен сравниваться равным исходному указателю.

3 Ан целочисленное константное выражение со значением 0, или такое выражение приведено к типу
void *, называется константа нулевого указателя.
55) Если константа нулевого указателя преобразуется в
тип указателя, результирующий указатель, называемый нулевым указателем, гарантированно сравнивает неравные
на указатель на любой объект или функцию.

Так что любой целочисленное константное выражение который оценивает 0 является константой нулевого указателя и может быть преобразована в NULL указатель. Эффективно в вашем примере все указатели, кроме p4, p8 а также p9 нулевые указатели. p4, p8 а также p9 не должны быть нулевыми указателями, так как их инициализация не является константным выражением, поскольку содержит переменные (даже если const Квалифицированный).

Вот еще один ответ о NULL в C ++, Для записи.

9

какой из p1, p2, а также p3 будут нулевые указатели?

В C ++ 11 все они. В соответствии с пунктом 4.10 / 1 стандарта C ++ 11:

константа нулевого указателя является целочисленным константным выражением (5.19) prvalue целочисленного типа, которое оценивается как
ноль или тип значения std::nullptr_t, […]

Поэтому, согласно терминологии Стандарта, все, что является постоянная (интегральное) выражение и оценивает 0 это константа нулевого указателя (не нулевой указатель, еще). Единственное, которое не является константным выражением, которое оценивает 0 или тип значения nullptr_t в вашем примере это zeroпотому что это не постоянное выражение.

Абзац продолжается:

Константа нулевого указателя может быть преобразована в тип указателя;
Результатом является значение нулевого указателя этого типа и отличается от любого другого значения указателя объекта или
тип указателя на функцию. Такое преобразование называется преобразование нулевого указателя. Два значения нулевого указателя
один и тот же тип должен сравниваться равным.

Так что в вашем примере все указатели, кроме p4 являются значения нулевого указателя и сравнивать равных между собой.

8
По вопросам рекламы [email protected]