Какие еще определения NULL были на старых платформах?

Иногда можно прочитать, что старые компиляторы C имели определения NULL, которые не были 0 или (void *)0. Мое понимание стандарта C заключалось в том, что даже если битовый шаблон платформы для нулевого указателя отличен от нуля, целое число 0, приведенное к указателю (явно или неявно), по-прежнему является нулевым указателем и хранится внутри как бит нулевого указателя платформы. шаблон.

А вот например, здесь написано:

В некоторых старых компиляторах C NULL по-разному определяется для некоторых странных вещей, поэтому с ним нужно быть осторожнее.

Я помню, как читал это время от времени в других местах. Если это не устойчивая городская легенда, какие другие определения NULL использовались?


person ptomato    schedule 30.06.2013    source источник
comment
Я почти уверен, что некоторые системы использовали 0L в старые недобрые времена до стандарта C.   -  person Jonathan Leffler    schedule 30.06.2013
comment
@CarlNorum: я не думаю, что вопросы дублируются. Другой смотрит на ужасные несоответствующие определения (по крайней мере, согласно примеру в вопросе), тогда как на этот хорошо ответили бы соответствующие, но необычные определения.   -  person R.. GitHub STOP HELPING ICE    schedule 30.06.2013


Ответы (2)


Вы абсолютно правы, когда говорите, что константа нулевого указателя (постоянный целочисленный нуль или постоянный целочисленный ноль, приведенный к void *) гарантированно будет правильно преобразована в соответствующее внутреннее представление нулевого указателя для целевого типа. Это означает, что нет необходимости в каком-либо другом определении NULL. 0 или (void *) 0 будут работать везде.

Однако в то же время самые ранние версии языка C не давали такой гарантии и не имели стандартного макроса NULL. Присвоение целочисленного значения переменной указателя приводило к тому, что указатель буквально указывал на адрес, представленный этим целочисленным значением. Присвоение константы 0 указателю просто приводит к тому, что он указывает на адрес 0. Если пользователи хотели иметь зарезервированное значение указателя в своей программе, им приходилось вручную выбирать «одноразовый» адрес для использования с этой целью.

Вполне возможно, что макрос NULL стал использоваться неофициально до стандартизации языка и до того, как появилось вышеупомянутое правило преобразования нуля в указатель. В то время NULL должно было быть определено как целочисленное значение, представляющее этот точный зарезервированный адрес. Например. предстандартная реализация C, которая хотела использовать адрес 0xBAADFOOD для нулевых указателей, определяла бы NULL как 0xBAADFOOD. Я не могу подтвердить это, так как я не знаю, когда именно макрос NULL впервые появился «в дикой природе».

person AnT    schedule 30.06.2013

Вы абсолютно правы.

Одна из "странных вещей", с которой вы можете столкнуться, это #define'ing NULL в ((void *)0), что приведет к сбою кода, использующего NULL как что угодно, кроме указателя.

Вот еще несколько вариаций:

http://www.tutorialspoint.com/c_standard_library/c_macro_null.htm

#define NULL ((char *)0)

or

#define NULL 0L

or

#define NULL 0

Также стоит отметить, что C++ 11 вводит nullptr, чтобы обеспечить безопасное для типов устранение неоднозначности NULL, 0 и т. д. См. Много шума из ничего или (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1601.pdf

person paulsm4    schedule 30.06.2013
comment
И иметь код, который злоупотребляет NULL fail, — это прекрасно! - person Jonathan Leffler; 30.06.2013
comment
Вот несколько веских аргументов в пользу использования 0 вместо NULL: Какие еще определения NULL были на старых платформах? - person paulsm4; 30.06.2013
comment
Но char c = NULL; генерировать предупреждение лучше, чем пропускать его без комментариев. - person Jonathan Leffler; 30.06.2013