Почему / Когда использовать (!! p) вместо (p! = NULL) - PullRequest
7 голосов
/ 22 октября 2009

В следующем коде какая польза от использования (!!p) вместо (p != NULL)?

AClass *p = getInstanceOfAClass();
if( !!p )
  // do something
else 
  // do something without having valid pointer

Ответы [ 7 ]

11 голосов
/ 22 октября 2009

Это почти то же самое, хотя я считаю !!p плохим стилем и обычно указывает, что кодер пытается быть умным.

9 голосов
/ 22 октября 2009

Это вопрос стиля, на самом деле они эквивалентны. См. этот очень похожий вопрос для обсуждения.

Сравнение IMO с нулевым указателем яснее.

7 голосов
/ 22 октября 2009

Я думаю, что оригинальный комментарий GMan должен быть принятым ответом:

Интересно, что не так с просто if (p)

Дело в том, что ничего не так с этим, и этот должен быть предпочтительным способом. Во-первых, !!p «слишком умный»; это также совершенно не нужно и, следовательно, плохо (обратите внимание: мы говорим об указателях в выражении if здесь, поэтому комментарий Anacrolix, хотя и в целом действительный, здесь не применяется!).

То же самое относится и к p != NULL. Хотя это возможно, это просто не нужно. Это больше кода, это полностью избыточный код и, следовательно, это делает код хуже. Джефф Этвуд когда-либо говорил, что «лучший код - это вообще не код». Избегайте избыточного синтаксиса. Придерживайтесь минимума (который все еще передает полное значение; if (p) является завершенным).

Наконец, if (p), пожалуй, самый идиоматичный способ написать это на C ++. C ++ наклоняется назад, чтобы получить то же поведение для других типов в языке (например, потоков данных), за счет некоторых очень странных причуд. Следующая версия стандарта даже вводит новый синтаксис для достижения этого поведения в пользовательских типах.

Для указателей мы получаем то же самое бесплатно. Так что пользуйся.

/ EDIT: про ясность: sharptooth пишет, что

Сравнение IMO с нулевым указателем более понятное.

Я утверждаю, что это объективно неправильно: if (p) яснее. Нет никакого способа, которым это утверждение могло бы означать что-либо еще, ни в этом контексте, ни в любом другом, в C ++.

3 голосов
/ 22 октября 2009

Насколько я вижу, это просто более короткий способ преобразовать его в логическое значение. Это относится! хотя дважды, тогда как p != NULL делает одно сравнение. Поэтому я предполагаю, что выгода заключается лишь в более коротком коде, хотя и более загадочном, если вы не знаете, что означает !!p.

0 голосов
/ 22 октября 2009

Нет разницы в данном примере.

Однако предположение, что это относится ко всем случаям, неверно. a = не не b - это не то же самое, что a = b , что касается целочисленных типов.

В C 0 ложно. Все, кроме 0, правда. Но not 0 - это 1, и ничего больше. В C ++ значение true приводит к 1 как целому числу не только для обратной совместимости с C, но и потому, что 1 не является 0, а 1 является наиболее распространенным значением, используемым для обозначения true в типах C bool, включая официальный тип C bool и BOOL, используемые в Win32.

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

Этот метод известен как идиома двойного взрыва, и этот парень дает несколько хороших оправданий .

0 голосов
/ 22 октября 2009

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

0 голосов
/ 22 октября 2009

Они одинаковые, но я рекомендую использовать

NULL != p

Это более читабельно.

...