2010-08-18 3 views
3

Варианты A:Как выбрать нулевой указатель на C++?

if (NULL == pSomethingColumn) // Yes, we use Yoda conditions 
if (NULL != pSomethingColumn) 

Или

if (pSomethingColumn) 
if (!pSomethingColumn) 

Я ищу ссылки, объясняющих рассуждения, а также.

Я слышал, что некоторые люди говорят, что технически NULL не обязательно должен быть указан как 0, но давай! если бы это было так, то присоска (наше приложение) потерпела бы крах в -2147483648 разными способами.

Итак, если NULL != 0, то у нас будут большие проблемы.

Пожалуйста, помогите мне решить бессмысленное обсуждение синтаксиса. Я не особенно привязан ни к какому пути; просто ищет официальный путь. Благодарю.

P.S. Мы используем компилятор Visual Studio C++.

+8

Я уверен, что 'NULL' должно быть 0 на любом соответствующем компиляторе. – dreamlax

+0

@dreamlax, можете ли вы придумать ссылку/ссылку? –

+4

@Hamish Grubijan: C++ standard 4.10 «Константа нулевого указателя является интегральным постоянным выражением (5.19) rvalue целочисленного типа, который оценивается в 0». и 18.1 «Макрос NULL - это константа нулевого указателя C++, определяемая реализацией». Сноски на одной странице показывают, что '0' и' 0L' действительны для 'NULL', но не' (void *) 0'. – dreamlax

ответ

9

Ни один из них явно не лучше другого. С технической точки зрения они эквивалентны. Число 0 в контексте указателя не означает, что все биты равны нулю; он определен как эквивалент любого битового шаблона, используемого для представления нулевых указателей. NULL может быть определен как 0 или (void *) 0. Любое определение является синтаксическим и ничего не говорит о представлении базового бита.

Таким образом, if (!p) - это то же, что и if (p == NULL) - это то же самое, что и if (p == 0) с технической точностью.

Вопрос является одним из стилей. Как и все проблемы стиля, ваша первая склонность должна соответствовать всем существующим стандартам кодирования. Сделайте то же самое, что и остальная часть кода. Если нет преобладающего стандарта, тогда это сводится к личным предпочтениям, и вам будет предложено разработать стандарт кодирования со своими сверстниками.

(Лично мне нравится использовать явные сравнения и оставляет за собой короткий синтаксис для логических значений, но я с удовольствием использовать if (!p) это то, что делают все остальные.)

+0

+1 за рекомендацию следовать за стадом. Это на самом деле самое важное, когда ваш код будет передан группе. –

+0

Это C++, 'NULL' не может быть' (void *) 0' в противном случае инициализации, такие как 'int * p = NULL;', были бы незаконными. –

+1

Также 'if (! P)' эквивалентно 'if (p == 0)' not 'if (p! = 0)'. –

11

Я считаю случайностью истории, что ноль соответствует к ложному и ненулевому соответствует true; Мне нравится резервировать эти формы только для булевых выражений. Однако у меня нет проблем с тем, чтобы увидеть эту форму в чужом коде.

Мой голос:

if (pSomethingColumn == NULL) 

Нет, я никогда не был укушен позабыв один из знаков равенства. Просто повезло, или, может быть, очень осторожно.

+2

Его также более естественно читать так, и все современные компиляторы предупреждают вас, если вы случайно выполняете задание в выражении if (и поскольку вы (мы/все мы) рассматриваем предупреждения как ошибки, они не будут компилироваться) :-) –

+0

@ Мартин Йорк, знаете ли вы, знаете ли вы, что компилятор Visual Studio 2010 C++ (неуправляемый и управляемый) предупреждает вас? –

+2

@Hamish: да, но только на уровне предупреждения 4. –

3

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

Чтобы использовать NULL, вы должны указать #include заголовок, который определяет его как <cstddef>; вы всегда можете использовать 0.

При преобразовании в bool значение нулевого указателя всегда преобразуется в false; любое другое значение указателя всегда преобразуется в true.

При использовании в качестве аргумента унарного ! значение указателя преобразуется в bool, как указано выше, а затем отменяется.

Пока NULL определяется их эквивалентны:

if (NULL == pSomethingColumn) 
if (pSomethingColumn == NULL) 
if (0 == pSomethingColumn) 
if (pSomethingColumn == 0) 
if (!pSomethingColumn) 

и они эквивалентны:

if (NULL != pSomethingColumn) 
if (pSomethingColumn != NULL) 
if (0 != pSomethingColumn) 
if (pSomethingColumn != 0) 
if (pSomethingColumn) 
0

Я использую (! PSomethingColumn), потому что я ленивый, но (pSomethingColumn == NULL) является более выразительным, поскольку он показывает, что переменная предназначена для указателя.

+0

Так же факт, что переменная называется 'pSomethingColumn'. – dreamlax

+0

@dreamlax, 'pSomethingColumn' был предоставлен мной, задающимся вопросом по этому вопросу. У меня есть привычка не раскрывать точные имена переменных; вот как я параноик. –

+1

@dreamlax: Это означает, что кто-то поднял плохую привычку в 1980-х годах. Только объявление переменной сообщит вам, какой тип это на самом деле. –

3

Назовите меня эксцентричным, но я действительно предпочитаю один из каждого набора. Я бы использовал if(ptr), если я собираюсь сделать что-то, что специально требует указателя на существование. Я бы использовал if(NULL==ptr), если я собираюсь сделать что-то, что специально требует, чтобы указатель был NULL. Думаю, это связано с теорией о том, что легче читать утверждения, которые не отрицаются.

Чем больше веселей ... if(!(0 != !ptr))

+1

Ах, дерьмо, ты только что придумал третий путь. –

+0

Лично я стараюсь избегать if (! Ptr), потому что это случалось не раз, что я не видел! до ptr, и поэтому я догадался, что тест ошибочен. И когда я вижу, что (! (0! =! Ptr)), я делаю поиск в SVN, чтобы узнать имя автора, просто чтобы узнать, все еще находится этот психопат. :-) –

+0

Кстати, вы всегда можете сделать больше психопатически нечитаемых, что вы думаете об этом? : if (! (0! =! (ptr ++))) –

1

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

Относительно нулевых указателей: в то время как представление из нулевого указателя зависит от конкретной реализации, и не обязательно является значение, равным нуля, константа пустого указателя представляет собой целое число константы с нулевым значением. Таким образом, NULL должен быть определен как нечто, конвертируемое в целочисленное значение нуля - наиболее очевидным определением является 0.

+0

Хм ... возможно, я должен был спросить - что использует Google/MSFT? –

+1

@ Хамиш: руководство по стилю Google не входит в этот уровень нерелевантных деталей. На протяжении десятилетий у Microsoft были всевозможные дурацкие соглашения, но я уверен, что их нынешние соглашения также не беспокоятся о таких деталях. Просветленное руководство по стилю должно содержать правила, которые приводят к поддерживаемому коду, а не указывать, как писать код до последнего символа. –

+0

это хороший момент. Тем не менее, в мире C# я с удовольствием следую правилам StyleCop, которые охватывают самые мелкие детали, даже если я не согласен с 5% из них. Я хочу, чтобы что-то подобное существовало для C++. –

1

Я всегда предпочитаю

if (pSomethingColumn != NULL) 

Не только потому, что это в основном & концептуально правильно, но и потому, что это самодокументирующимся. Использование конкретной конструкции только потому, что «она работает» - это верный рецепт непереносимости.

+0

Спасибо, и каково ваше отношение к условиям Yoda, например 'if (NULL == x)' или 'if (NULL! = X)'? –

+1

Я понимаю преимущества нотации Yoda, но для меня это не кажется естественным, поэтому я его совсем не принял. Мне нравится читать и писать код так, как я думаю, что на самом деле соответствует моему первому ответу. –

1

NULL обязательно соответствует 0 в любом соответствующем компиляторе C++. Лично я предпочитаю использовать NULL, потому что IMHO является более явным, и цель понятна. Но Bjarne Stroustrup uses 0 вместо NULL, потому что он предпочитает избегать макросов. C++ 0x будет иметь явное ключевое слово nullptr, которое, мы надеемся, устранит эту проблему раз и навсегда.

Смежные вопросы