В чем смысл ставить константы в операторах if в первую очередь? - PullRequest
58 голосов
/ 26 января 2010

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

if ( NULL == pMsg ) return rv;

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

Ответы [ 8 ]

79 голосов
/ 26 января 2010

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

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

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

29 голосов
/ 26 января 2010

Чтобы остановить вас от написания:

 if ( pMsg = NULL ) return rv;

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

8 голосов
/ 26 января 2010

Чтобы пояснить, что я написал в некоторых комментариях, вот причина , а не , чтобы сделать это в коде 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 голосов
/ 26 января 2010

Останавливает ошибку одиночного = назначения.

Например,

if ( NULL = pMsg ) return rv;

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

if ( pMsg =  NULL) return rv;

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

7 голосов
/ 26 января 2010

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

2 голосов
/ 26 января 2010

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

2 голосов
/ 26 января 2010

Они сказали: «Чтобы не смешивать присваивание и сравнение».

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

0 голосов
/ 27 января 2010

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

...