LINUX.ORG.RU

Ответ на: комментарий от olegk

Стандарт не читал, но NULL=0

NULL == 0 далеко не во всех стандартах. Во многих стандартах значение NULL не определяется. Сам сталкивался в практике с ненулевыми значениями. У знакомого в одном варианте (не PC, кажется) было 0xFFFFFFFF для выбрасывания аппаратного исключения при чтении по NULL (ибо 0x00000000 был корректным адресом). Сам же немало программировал под DOS, где NULL был указателем сегмент:смещение на обрабочик исключения, чтобы при вызове функции по NULL сгенерировалось программное исключение.

Вообще, мы на эту тему много бурчали на http://balancer.ru/g/p1701546 и далее

KRoN73 ★★★★★
()
Ответ на: комментарий от olegk

Стандарт не читал

Кто не читал, просьба не мусорить. Стандарт не обязывает, чтобы NULL было (void *)0. Он требует, чтобы это была какая-то зависящая от реализации константа с требуемыми свойствами (в частности, чтобы не один указатель на «настоящие» данные не был равен NULL). То есть вроде бы можно делать штуки типа #define NULL (void*)(-1).

Но на stackoverflow прочитал, что в сравнениях якобы можно писать if (NULL) и if (!NULL) и это будет работать как ожидается. Читал стандарт — нехера не понял. Английский слабоват.

toady2
() автор топика

Вообще, непонятно, зачем искать приключения и писать !NULL? :)

KRoN73 ★★★★★
()
Ответ на: комментарий от toady2

Но на stackoverflow прочитал, что в сравнениях якобы можно писать if (NULL) и if (!NULL) и это будет работать как ожидается

Но в чём смысл таких записей? И, боюсь, в общем случае оно работать не будет. Правильно, всё же, if(ptr == NULL) или if(ptr != NULL)...

KRoN73 ★★★★★
()

ISO/IEC 9899:TC3 6.3.2.3/3

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant[55] If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function

Целочисленная константное выражение со значением 0 (или подобное выражение, приведённое к типу void *) называется null pointer constant[55]. Эта константа, будучи привёденной к типу указателя, называется null pointer и гарантированно не совпадает/не равна любому объекту или функции.

55

The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant; see 7.17.

Макрос NULL определён в <stddef.h> (и других заголовочных файлах) как null pointer constant

schizoid ★★★
()
Ответ на: комментарий от schizoid

или подобное выражение

Что значит «подобное»? Где этот абзац мне запрещает определять null-pointer как (void*)(-1)?

toady2
() автор топика

С NULL надо сравнивать. К NULL можно приравнивать. Пожалуй, всё.

Остальное - ССЗБ

yoghurt ★★★★★
()
Ответ на: комментарий от toady2

Это я хреново перевёл. Надо так:

Целочисленная константа 0 (или выражение с численным значением 0, приведённое к типу void*) ...

Этот абзац нигде не упоминает о физической реализации машинной памяти и её особенностях. Про dereferencing ни слова. NULL здесь определяется как ничему не равное значение.

schizoid ★★★
()
Ответ на: комментарий от thesame

То есть, все реализации, в которых NULL != 0 нарушают стандарт?

Один конкретный — да. Но стандартов много :)

KRoN73 ★★★★★
()
Ответ на: комментарий от schizoid

NULL здесь определяется как ничему не равное значение.

Не. NULL определяется как значение, которое не равно никакому реальному указателю.

toady2
() автор топика

Мне кажется, что этот код будет работать всегда.

Константа NULL _всегда_ определяется как некая форма нуля, вне зависимости от внутреннего представления невалидного указателя. Т.е. это может быть либо целый ноль (0), либо ноль, прведенный к какому-нибудь указателю ((void*)0).

Эти ситауции немного разные, но дают одинаковый результат. Надо еще заметить, что стандарт говорит, что if (a) буквально означает if (a != 0). Плюс, если не ошибаюсь, то !а должно означать то же, что и (а == 0). Т.о. в первом случае получается буквально

if (0 == 0)
    foo();
и условие тут будет истино, т.к. !0 это явно не 0.

Во втором случае имеем

if ( ((void*)0) == 0 )
    foo();
Тут внутри скобок мы имеем сравнение двух указателей, для которых, опять же, сравнение с нулем должно выполняться вне зависимости от внутреннего представления невалидного указателя.

gaga
()
Ответ на: комментарий от KRoN73

NULL == 0 далеко не во всех стандартах.

Да ну? Его бинарное представление - да, не обязательно 0x00000000, но вычисляется он в 0

legolegs ★★★★★
()

NULL это указатель на неверный адрес. 0 это или нет — зависит от имплентации. Вопросы есть?

Rzhepish
()

что же вы несете... тогда все выражения if (pointer) or if (!pointer) проверяющие указатель на недейсвительный бажные получается ? если и есть такой компилятор то закопать и выкинуть на помойку ведь на него не скомпилиш не один существующий проект а вообще некоторые ССЗБ пишут if (pointer != NULL) or if (pointer == NULL) что думаете о них они совсем умом тронулись или просто говнокодеры ?

anonymous
()
Ответ на: комментарий от legolegs

Посмотри по ссылке выше. Там этот вопрос перетёрли плотно.

но вычисляется он в 0

Не всегда.

KRoN73 ★★★★★
()
Ответ на: комментарий от Rzhepish

NULL это указатель на неверный адрес. 0 это или нет — зависит от имплентации. Вопросы есть?

то, что ты полный неуч, и так очевидно:

1. выражение в if сравнивается на неравенство 0;
2. оператор !p также эквивалентен по стандарту выражению p != 0;
3. NULL всегда приводится к 0( по стандарту ).

Вопросы есть?

anonymous
()
Ответ на: комментарий от anonymous

оператор !p также эквивалентен по стандарту выражению p != 0;

т.е. p == 0, см. 6.5.3.3

anonymous
()
Ответ на: комментарий от KRoN73

Посмотри по ссылке выше. Там этот вопрос перетёрли плотно.

ок читаем по ссылке

Ну и NULL вовсе не 0 часто.

ок допустим читаем дальше

в логических выражениях NULL приводится неявно к false

тоесть кем бы не был NULL в условии он примет false ? в чем смысл вашей рекомендации писать if (pointer == NULL) ?

и еще тогда вопрос часто функции принимают указатели но можно и передать NULL указатель что бы показвать что этот параметр не нужен но при вызове часто пишут не NULL а 0 типа func(0,0,0,0) что этот код тоже на помоечку вместе с if (!pointer) ? ну тут как бы понятно 0 неявно приводится к NULL если прототип виден функции в итоге «допустим» он может после преобразования стать вовсе не нулем а вот про if (!pointer) не понятно

anonymous
()

Новый тип срача: NULL-срач. Далеко не первый раз в development, а комментаторы словно респаунятся с опять нулевыми знаниями.

Pavval ★★★★★
()
Ответ на: комментарий от anonymous

3. NULL всегда приводится к 0( по стандарту ).

Процитируйте пожалуйста соотв. место в стандарте.

toady2
() автор топика
Ответ на: комментарий от KRoN73

можешь дать ссылку, когда это не так? Насколько мне известно, компилятор заботится о том, чтобы в выражении p == 0 этот ноль был правильным null-адресом для данной машины, при этом в прикладном коде поишется все равно «0». Соотвественно и NULL определяется как 0.

У меня нет сейчас стандарта, вот нагуглил ссылку на c-faq: http://c-faq.com/null/macro.html (не ахти какой авторитет, конечно)

gaga
()
Ответ на: комментарий от toady2

Процитируйте пожалуйста соотв. место в стандарте.

перепутал таки, это 0 кастится к поинтеру, что таки не отменяет факта, что if( p ) и if( !p ) вполне легальны

anonymous
()
Ответ на: комментарий от gaga

У меня нет сейчас стандарта

google c99 pdf

toady2
() автор топика
Ответ на: комментарий от anonymous

что таки не отменяет факта, что if( p ) и if( !p ) вполне легальны

Процитируйте, пожалуйста, места в стандарте, где это подтверждается.

toady2
() автор топика
Ответ на: комментарий от gaga

можешь дать ссылку, когда это не так?

Я сейчас не программирую на Си/Си++ на не PC платформах :)

Насколько мне известно, компилятор заботится о том, чтобы в выражении p == 0 этот ноль был правильным null-адресом для данной машины

Ты избалован современными популярными компиляторами :D

У меня нет сейчас стандарта

Какого стандарт_а_? Радует меня в этой теме постоянная отсылка на некий _стандарт_ :) Стандартов дофига разных, ещё больше компиляторов, не отвечающих на 100% современным стандартам. Мир не кончается на GCC/ICC на x86 во flat-моделях :)

Я уже упоминал по ссылке какой-то из древних, то ли Watcom'ов, то ли Zortech'ей (давно было), в котором NULL указывал на сегмент:смещение обработчик NPE. Привеление к long int давало отнюдь не нулевое число. Ибо сам NULL был определён там именно как число и как не нулевое.

Mishka по ссылке, кстати, опытный компиляторщик, упоминает архитектуру, где NULL был равен (численно) 0xFFFFFFFF.

Не могу ручаться, но, кажется, NULL был ненулевым в Си-компиляторе на Casio PV, под PV-OS. По-моему, там 0 был тоже допустимым адресом, а компилятор был крайне примитивен для того, чтобы как-то особо, а не как число отрабатывать NULL. Но тут проверить не смогу, машинку подарил лет 8 назад.

KRoN73 ★★★★★
()
Ответ на: комментарий от toady2

Процитируйте, пожалуйста, места в стандарте, где это подтверждается.

6.3.2.3 Pointers
«An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant»

6.8.4.1 The if statement
the first substatement is executed if the expression compares unequal to 0.

6.5.3.3 Unary arithmetic operators
The expression !E is equivalent to (0==E).

anonymous
()
Ответ на: комментарий от toady2

ну и в «6.5.9 Equality operators» сказано, что два null pointers всегда равны между собой

anonymous
()
Ответ на: комментарий от toady2

Давайте под стандартом договоримся понимать текущий ISOшный C99.

И что делать с компиляторами, которые его не соблюдают? :)

Да и по этому стандарту есть ряд вопросов — выше в теме они озвучивались.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

И что делать с компиляторами, которые его не соблюдают? :)

Это вопрос третий. В стартовом сообщении про компиляторы не спрашивалось.

toady2
() автор топика
Ответ на: комментарий от toady2

В стартовом сообщении про компиляторы не спрашивалось.

Так спор давно не о стартовом сообщении, а о том, как правильно :)

А правильный формат известен давно, не вызывает неопределённостей с любыми компиляторами и стандартами и логически легко читается. Это явное сравнение с NULL.

KRoN73 ★★★★★
()
Ответ на: комментарий от anonymous

а давайте лучше посчитаем процент программистов столкнувшихся с багами из за представления недействительного указателя не нулем и подумаем стоит ли вообще загонятся по этому поводу а то похоже на то что мы больные на голову люди решаем ненужные проблемы

anonymous
()

Если не изменяет склероз, то вроде так определялось

NULL = 0;
NULL = 0L;
NULL = (void *)0;
Boy_from_Jungle ★★★★
()
Ответ на: комментарий от anonymous

Несколькими постами ранее была цитата из стандарта, опровергающее ваше утверждение. Более того, в большинстве случаев NULL как раз не 0, а (void *)0.

Для тех, кому, как в первом классе, нужно несколько прочтений для понимания, повторю ещё раз: меня интересует мнение С99 по поводу данного вопроса. Агенство ОТС (Одна Тёта Сказало), НЯП (Насколько я Помню) и прочие не интересуют абсолютно.

toady2
() автор топика
Ответ на: комментарий от KRoN73

А правильный формат известен давно, не вызывает неопределённостей с любыми компиляторами и стандартами и логически легко читается. Это явное сравнение с NULL.

окей давай те тогда приведем список мест где надо явно использовать NULL кроме сравнения в условиях где еще ?

anonymous
()
Ответ на: комментарий от toady2

ещё и сообщение удалил.

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant

тупой совсем, да?

anonymous
()
Ответ на: комментарий от toady2

да ты совсем болезный, я смотрю.

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant

An integer constant expression with the value 0

ты это прочитать осилил, а? Что такое ИЛИ ты знаешь?

anonymous
()
Ответ на: комментарий от KRoN73

Хотя если явно же, то бородатые дяди рекомендуют

if(NULL == prt)
ну понятно чтобы не провтыкать
if(prt = NULL)
а потом не тратить время на свой же провтык

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от Boy_from_Jungle

Всегда писал так

Если тебе завтра потребуется писать не под PC-платформу, то эта привычка может выйти боком. Ну и плюс в твоём случае придётся использовать венгерскую нотацию, чтобы сразу было видно, что это указатель. А в сравнении с NULL указатель виден по логике.

KRoN73 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.