LINUX.ORG.RU

NULL, true и 0 в C и C++


0

0

Эквивалентно ли (по стандарту и фактически)

void *ptr - if (ptr) и if (ptr != NULL) - if (ptr) и if (ptr != 0)

int i; - if (ptr != 0) и if (ptr)

Встречал разные варианты. Интересует С и С++. Спасибо!

anonymous

>Эквивалентно ли (по стандарту и фактически)

Подобные вопросы так настойчиво задаются как будто это вообще самые серьезные проблемы при написании или портировании кода на C и С++, бугога.

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

>#define NULL 2 // 8)

Память выдается страницами по 4 кб, так что адреса от нулевого до 4096-го зарезервированы под отлов ошибок типа разыменовывания нулевого указателя. Так чта 0x00000002 под нулевой указатель вполне сойдет.

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

... Хотя нет, не сойдет - if(p) и проч. работать не будут

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

> Память выдается страницами по 4 кб, так что адреса от нулевого до 4096-го

4095-го :D

Ну а вообще под эти цели выделено больше, чем страница.

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

>>Память выдается страницами по 4 кб

>ржунимагу.

Ну на уровне процессора это минимальная гранулярность при выдаче прав доступа если я правильно помню книжку по защищенному режиму процессора i486. Насчет x86_64 не скажу.

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

> Ну на уровне процессора это минимальная гранулярность при выдаче прав доступа

Можно сегменты использовать. У них "гранулярность" - 1 байт. И спектр правов ширше. :)

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

>> Ну на уровне процессора это минимальная гранулярность при выдаче прав доступа

>Можно сегменты использовать. У них "гранулярность" - 1 байт. И спектр правов ширше. :)

А линукс как делает? Я всегда думал что как винда - т.е страницами.

Absurd ★★★
()

Ну и по теме: IIRC, в Си++ литерал 0 преобразуется в любой указатель, поэтому в Си++ любой указатель можно сравнивать с литерало 0, и NULL определен как 0.

В Си никакие целые числа в указатели неявно не преобразуются, поэтому сравнение указателя с 0 вызовет предупреждение. Однако в Си void* неявно преобразуется к любому указателю, поэтому сравнение void* с любым указателем разрешено, и NULL определен как ((void *)0).

Ну а if (ptr) разрешен в обоих языках.

P.S. в стандарты не заглядывал, примеры компилятором не проверял :)

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

> >> Ну на уровне процессора это минимальная гранулярность при выдаче прав доступа

> >Можно сегменты использовать. У них "гранулярность" - 1 байт. И спектр правов ширше. :)

> А линукс как делает? Я всегда думал что как винда - т.е страницами.

Страницы и сегменты вещи ортогональные в общем-то. В линукс были же попытки задействовать сегментацию x86 для неисполняемого стека, ЕМНИП.

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

> В Си никакие целые числа в указатели неявно не преобразуются, поэтому сравнение указателя с 0 вызовет предупреждение.

Да ну? Правда штоле?

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

>> В Си никакие целые числа в указатели неявно не преобразуются, поэтому сравнение указателя с 0 вызовет предупреждение.

> Да ну? Правда штоле?

По другим пунктам возражений нет, чучелко?

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

>>>Память выдается страницами по 4 кб

>>ржунимагу.


>Ну на уровне процессора это минимальная гранулярность при выдаче прав доступа если я правильно помню книжку по защищенному режиму процессора i486. Насчет x86_64 не скажу.


воот. x86 - это совсем не единственная архитектура в мире. в моем роутере, например, размер страницы равен 16кб. а в мобильнике вообще MMU нет, там по нулевому адресу лежит вектор прерывания перезапуска.

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

> Спасибо за разьяснение.

Не за что :) Чучелко право - даже в Си литерал 0 неявно преобразуется в указатель любого типа, так что сравнение указателя c 0 или присваивание 0 указателю являются правильными конструкциями, по крайней мере в Си99 ("An integer constant expression with the value 0, or such an expression cast to type void*, is called a null pointer constant"). Правда, насчет более ранних стандартов не уверен - документов под рукой нет.

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

>Круто. А я - то и не догадывался.

А если догадывался, выходит, нарочно лгал?

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

Видимо, поэтому Страуструп рекомендует не использовать NULL. Вместо него использовать 0.

dave ★★★★★
()

имхо, если man/стандарт говорит, что функция возвращает NULL, значит правильней сравнивать с NULL.

если говорит, что возвращает нулевой адрес - значит надо сравнивать if(ptr) / if(!ptr)

и лучше бы без ==0 / !=0 , ибо опять-таки число преобразовывать к указателю не кошерно

xydo ★★
()

ЕМНИП то ли Мейерс, то ли Александреску в одной из книг по плюсам делали целый класс дня NULL, учитывая все ньюансы его использования. Как то так. Точно не помню

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