Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
[C++] И мои 5 копеек 05.03.05 12:31 Число просмотров: 2444
Автор: amirul <Serge> Статус: The Elderman
|
> Немного "кулаками после драки", но всё же выскажусь :) > > > Не понял проблемы. NULL определено как ((void *)0) и в > C > > может неявно приводиться к указателю на любой тип. > Вы будете удивлены, но определение NULL как (void *)0 не > соответствует стандарту, как я недавно узнал (правда,
Я не удивлен, потому как это точно есть где то в страуструпе и именно поэтому я по памяти сделал свое первое заявление (о том что лучше делать не (!ptr) а (ptr == NULL)). Более того я удивился когда увидел в стандарте совершенно обратное.
> стандарту C++, не C - но я подозреваю, что и последнему > тоже). Стандарт явным образом прописывает, что NULL должен > быть целой константой и определение как (void *)0 НЕ > подходит.
Вообще то подходит. Литеральный 0 преобразованный к указателю на любой тип является NULL-pointer-ом, хотя его двоичное представление может отличаться от представления самого нуля (но это уже проблемы компилятора). Следовательно ((void *)0) всегда будет иметь значение NULL. С другой стороны NULL - не является ключевым словом ни в C ни в C++ следовательно его можно засунуть только в библиотеку. В C из двух вариантов переменная или макрос совершенно резонно был выбран макрос. В C++ появляется еще третий вариант - константная переменная, которая хоть и занимает место в секции констант, но все равно обращения к ней будут соптимизированы в тот же вид, что и с макросом. Оставлен макрос - ну и фиг с ним.
> Однако благодаря процитированному в глубине нитки > параграфу целый 0 может быть неявно приведён к указателю на > любой тип. > Отсутствие сравнения в условии эквивалентно сравнению с > литеральным нулём (не с NULL). Логическое отрицание > гарантированно делает не-нулевые указатели нулём (не > указателем, к слову), а нулевой указатель - ненулевым целым > значением (не помню точно, но по-моему, Стандарт не > определяет значение для !0, оговаривая лишь, что !0 != 0). > Соответственно, сравнивать результат логического отрицания > с указателем нельзя (компилятор как минимум выдаст > предупреждение).
А никто и не собирался сравнивать с указателем ;-P. Выбирался более правильный из двух вариантов
(!ptr) и (ptr == NULL)
Лично мне больше нравится второй вариант, как более явно показывающий что я делаю. До вчерашнего дня я считал его еще и более соответствующим стандарту
> Вот. > P.S. Несмотря на то, что NULL, по стандарту - целое число, > производители компиляторов всё же стараются, чтобы длина > NULL равнялась длине указателя. Это позволяет спокойно > использовать NULL (в отличие от 0), для указания конца > переменного списка аргументов (в "функциях с > многоточиями").
Дык ты ж сам указываешь тип следующей переменной. Хоть 0, хоть NULL хоть вообще структура. И все это может быть маркером конца :-)
|
|
|