it-roy-ru.com

В чем смысл ставить константы в операторах if в первую очередь?

Я искал пример кода C++ для аппаратного интерфейса, с которым я работаю, и заметил много утверждений следующего содержания:

if ( NULL == pMsg ) return rv;

Я уверен, что слышал, как люди говорят, что ставить константу на первое место - хорошая идея, но почему? Это просто так, что если у вас есть большое утверждение, вы можете быстро увидеть, с чем вы сравниваете, или есть что-то еще?

58
Jon Cage

Чтобы не смешивать сравнение (==) с присваиванием (=).

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

По сути, это один из методов защитного программирования. Чтобы защитить себя от себя.

79
user151323

Чтобы помешать вам писать:

 if ( pMsg = NULL ) return rv;

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

29
anon

Чтобы прояснить, что я написал в некоторых комментариях, вот причина не сделать это в коде C++.

Кто-то пишет, скажем, строковый класс и решает добавить оператор приведения к const char*:

class BadString
{
public:
   BadString(const char* s) : mStr(s) { }

   operator const char*() const { return mStr.c_str(); }

   bool operator==(const BadString& s) { return mStr == s.mStr; }

   // Other stuff...

private:
   std::string mStr;
};

Теперь кто-то слепо применяет constant == variable "защитный" шаблон программирования:

BadString s("foo");

if ("foo" == s) // Oops.  This compares pointers and is never true.
{
   // ...
}

Это, IMO, более коварная проблема, чем случайное назначение, потому что с сайта вызова нельзя сказать, что что-то явно не так.

Конечно, настоящие уроки:

  1. Не пишите свои собственные строковые классы.
  2. Избегайте неявных операторов приведения, особенно при выполнении (1).

Но иногда вы имеете дело со сторонними API, которые вы не можете контролировать. Например, строковый класс _bstr_t, распространенный в Windows COM-программировании, страдает этим недостатком.

8
jamesdlin

Это останавливает ошибку single = assignment.

Например,

if ( NULL = pMsg ) return rv;

не скомпилирует, где как

if ( pMsg =  NULL) return rv;

скомпилирует и даст вам головную боль

8
Dan McGrath

Когда константа является первой, компилятор предупредит вас, если вы случайно напишите =, а не ==, поскольку присваивать значение константе недопустимо.

7
liwp

Они сказали, "чтобы не смешивать назначение и сравнение".

На самом деле я думаю, что это чепуха: если вы так дисциплинированы, что не забываете ставить константу слева, вы определенно не перепутаете '= 'с' == ', не так ли? ;)

2
Alexander Poluektov

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

2
SteveV

Я забыл статью, но цитата звучала примерно так: "Очевидно, легче вспомнить, чтобы сначала поставить константу, чем использовать ==";))

0
Joe