В чем разница между var_ptr==NULL
и NULL==var_ptr
? Есть ли изменения в разных арках?var_ptr == NULL и NULL == var_ptr разница в различных арках
ответ
Нет никакой разницы. Это всего лишь способ предотвратить непреднамеренные задания. Например:
if (var = true); // I meant to compare, but this will still compile
в противоположность:
if (true = var); // I meant to compare, but this WON'T compile
Они являются Yoda Conditions и в этом случае нет никаких причин, чтобы использовать их отдельно от выбора конкретного стиля кодирования.
Как написано в вики-статье, это считается преимуществом, что нежелательное назначение будет как ошибка, когда оператор присваивания =
используется вместо равен ==
оператора.
if (ptr = NULL) // valid code, may produce a warning on some compilers
if (NULL = ptr) // invalid, reported as error during compile time
Хотя, по моему мнению, читаемость последних намного хуже.
Существует выигрыш, когда вид Yoda условие используется (в Java или C#), как это:
"constant string".equals(yourVariableString)
Потому что нет шансов получить NullPointerException
Несомненно, Йода сказал бы' if (5 count ==) '...? ;-) Не скомпилировал бы. –
Некоторые люди предпочитают
NULL == var_ptr
вариант, поскольку он защищает от опечаток «присвоения» аварии, например
if (NULL = var_ptr) { ... }
может поднять синтаксическую ошибку, поскольку вы назначаете константу. Иными словами,
if (var_ptr = NULL) { ... }
является синтаксически правильным, но почти наверняка НЕ то, что вы намеревались.
Внутри компилятора вы все равно получите инструкцию, которая сравнивает значение указателя с постоянным значением нуля. Эта инструкция в большинстве процессоров существует только в одной форме (хотя иногда существует несколько способов достижения одной и той же цели, например AND R0, R0
- это то же самое, что и CMP $0, R0
(или, в некоторых архивах, MOV var_ptr, R0
будет устанавливать флаги так, чтобы следующая инструкция может быть «прыгать, если не равна нулю»), и в зависимости от архитектуры процессора она может быть быстрее, чем другой вариант, но в конце концов она по-прежнему представляет собой одно сравнение с постоянным нулем. самые тривиальные компиляторы должны иметь возможность оптимизировать любой из этих вариантов в одно и то же, независимо от того, какой вариант «это переменная NULL» вы решите использовать. (Вы оставили if (!var_ptr)
в списке вариантов - и, конечно же, есть еще несколько сложные способы достижения одного и того же результата, и я уверен, что кто-то с этим мышлением может придумать что-то сложное, что компилятор делает беспорядок).
Чтобы проверить, есть ли какая-то разница я составил небольшой фрагмент кода в VS 2012, режим отладки без оптимизации
int * p = NULL;
if (p == NULL) p = NULL;
if (NULL == p) p = NULL;
x86
if (p == NULL) -(disassembly)-> cmp dword ptr [p],0
if (NULL == p) -(disassembly)-> cmp dword ptr [p],0
x64
if (p == NULL) -(disassembly)-> cmp qword ptr [p],0
if (NULL == p) -(disassembly)-> cmp qword ptr [p],0
компилятор производит тот же код, независимо от того, есть ли у вас NULL
или p
. Таким образом, это только вопрос стиля, и вопрос о why to have non-lvalues on the left side? уже связан, а также сообщение wiki, ссылающееся на Yoda-Condition, которое дает некоторые подсказки, почему желательно не иметь lvalue слева.
Второй стиль часто используется для того, чтобы ошибка компилятора всплывала, если кодер случайно использует один знак равенства (оператор присваивания). Я не знаю других причин для этого. –
и в C++ 11 вы, конечно, будете использовать 'nullptr' – TemplateRex
Если только, sigh ... ;-) –