Будет ли компилятор VS2008 c ++ оптимизировать следующий оператор if?

if (false == x) { ...} 

в отличие от:

 if (!x) { ... } 

а также

 if (false == f1()) { ...} 

в отличие от:

 if (!f1()) { ... } 

Я думаю, что if (false == … версия более читабельна. Согласны ли вы или имеете другой трюк, который вы можете предложить? Будет ли это так же быстро? Спасибо.

Вот почему мне не нравится! X:

 if (25 == a->function1(12345, 6789) && 45 == b->function1(12345, 6789) && !c->someOtherFunction(123)) { ... } 

Следующее выглядит лучше:

 if (25 == a->function1(12345, 6789) && 45 == b->function1(12345, 6789) && false == c->someOtherFunction(123)) { ... } 

Хороший компилятор должен генерировать один и тот же код для обоих блоков кода.

Однако вместо того, чтобы беспокоиться о false == f1() vs. !f1() , вы должны быть более обеспокоены оценкой короткого замыкания в этом примере:

 if (25 == a->function1(12345, 6789) && 45 == b->function1(12345, 6789) && !c->someOtherFunction(123)) { ... } 

Некоторые компиляторы будут генерировать код, который пропустит выполнение функций b->function1() и c->someOtherFunction() , если произойдет вызов a->function1() , чтобы оценить что-то отличное от 25 – причина, которую компилятор уже знает результат всей инструкции if () в этой точке, чтобы она могла прыгать в нужном месте.

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

Я лично нахожу форму if (!x) { ... } наиболее читаемой, но в настоящее время все они приведут к тому же коду.

EDIT: В вашем примере я бы сделал следующее:

 if ( a->function1(12345, 6789) == 25 && b->function1(12345, 6789) == 45 && !(c->someOtherFunction(123))) { ... } 

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

Я думаю, что if (false == … версия более читабельна. Согласны ли вы или имеете другой трюк, который вы можете предложить?

Ты делаешь это неправильно.

false == x возвращает bool, который, очевидно, нужно сравнивать с true !

if (true == (false == x)) { ...} было бы лучше. Но это снова возвращает bool, поэтому, чтобы быть в безопасности, и сделать ваш код более читаемым, нам лучше сделать это:

if (true == (true == (false == x))) { ...} . И так далее. Как только вы начнете сравнивать логические значения с булевыми, где вы остановитесь? Результат всегда будет другим логическим, и чтобы быть последовательным, вы должны сравнить это с логическим.

Или вы могли бы научиться понимать язык, на котором работаете, и использовать if (!x) { ...} , который выражает именно то, что вы хотели.

Что вы на самом деле считаете более читаемым?

  • if (false == x) { ...} переводится как «Если это правда, что false равно x».
  • if (!x) { ...} переводит на “if x is not true”.

Можете ли вы честно, серьезно, действительно сказать, что первая форма «более читаема»? Вы когда-нибудь скажете это в предложении? «Если верно, что ложь равна x»?

Он не читается, он просто кричит любому программисту, читающему ваш код, что «я не понимаю, являются ли утверждения или логические значения».

C ++ резервирует следующие ключевые слова слева как альтернативы операторам справа:

 and and_eq bitand && &= & or or_eq bitor || |= | xor_eq xor ^= ^ not not_eq compl ! != ~ 

Если вы беспокоитесь о ! теряясь, not выделяется больше.

 if ( a->function1(12345, 6789) == 25 and b->function1(12345, 6789) == 45 and not c->someOtherFunction(123)) { ... } 

Это случай преждевременной оптимизации ( когда оптимизация преждевременна? ). Но компилятор будет генерировать тот же код (режим отладки MSVC 2008):

 if (!bVal) bVal = true; if (bVal == false) bVal = true; //translates to ; 70 : if (!bVal) cmp BYTE PTR $T5793[ebp], 0 jne SHORT $LN9@wmain push OFFSET $LN10@wmain call __RTC_UninitUse add esp, 4 $LN9@wmain: movzx eax, BYTE PTR _bVal$[ebp] test eax, eax jne SHORT $LN2@wmain ; 71 : bVal = true; mov BYTE PTR $T5793[ebp], 1 mov BYTE PTR _bVal$[ebp], 1 $LN2@wmain: ; 72 : ; 73 : if (bVal == false) cmp BYTE PTR $T5793[ebp], 0 jne SHORT $LN11@wmain push OFFSET $LN10@wmain call __RTC_UninitUse add esp, 4 $LN11@wmain: movzx eax, BYTE PTR _bVal$[ebp] test eax, eax jne SHORT $LN1@wmain ; 74 : bVal = true; mov BYTE PTR $T5793[ebp], 1 mov BYTE PTR _bVal$[ebp], 1 

Профилировали ли вы и считали, что состояние является горячей точкой? Если нет, то сделайте все, что требуется для вашего стандарта кодирования.

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