“Если ([bool] == верный)” требуют еще одного шага, чем “если ([bool])”?

Можно не учесть новую строку, которая дает Вам:

case 1: case 2: case 3:
   break;

, но я рассматриваю тот плохой стиль.

28
задан Joel Coehoorn 9 December 2011 в 17:44
поделиться

14 ответов

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

Редактировать: Самый простой способ сказать - попробовать. Компилятор MS (cl.exe) генерирует такое же количество шагов при сборке:

int _tmain(int argc, _TCHAR* argv[])
{
    bool test_me = true;

    if (test_me) {
004113C2  movzx       eax,byte ptr [test_me] 
004113C6  test        eax,eax 
004113C8  je          wmain+41h (4113E1h) 
        printf("test_me was true!");
    }

    if (test_me == true) {
004113E1  movzx       eax,byte ptr [test_me] 
004113E5  cmp         eax,1 
004113E8  jne         wmain+61h (411401h) 
        printf("still true!");
    }
    return 0;
}

На этом этапе возникает вопрос, имеют ли test и cmp одинаковую стоимость? Я предполагаю, что да, хотя эксперты могут указать на различия.

Практический вывод: вам не стоит об этом беспокоиться. Скорее всего, у вас есть рыба намного более производительная, которую нужно жарить.

13
ответ дан 28 November 2019 в 02:41
поделиться

Я думаю сравнение с истиной показывает непонимание со стороны вашего партнера. Чтобы этого избежать, нужно называть Bools именами (например, isAvaliable : if (isAvailable) {...} ).

18
ответ дан 28 November 2019 в 02:41
поделиться

Я ожидал, что разница будет устранена с помощью любого полуприличного компилятора.

(Я только что проверил с помощью C #, и скомпилированный код точно такой же для обоих синтаксисов.)

16
ответ дан 28 November 2019 в 02:41
поделиться

Повторяющийся вопрос ( Что следует использовать: `! IsGood` или` IsGood == false`? ). Вот указатель на мой предыдущий ответ:

Специальная методика тестирования против истины или лжи - плохая практика если рассматриваемая переменная действительно предполагается использовать как логическое значение (даже если его тип не логический) - особенно в C / C ++. Тестирование против правда может (и, вероятно, приведет) к незначительные ошибки.

Подробности см. в следующем SO-ответе:

Следует ли мне использовать `! IsGood` или` IsGood == false`?

Вот ветка, в которой подробно объясняется, почему "== true" часто неверно в более подробных деталях, включая объяснение Страуструпа: https://qt-project.org/forums/viewthread/32642

10
ответ дан 28 November 2019 в 02:41
поделиться

Вот разборка Python (2.6):

>>> def check(x): return (bool(x) == True)

>>> import dis
>>> dis.dis(check)
  1           0 LOAD_GLOBAL              0 (bool)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1
              9 LOAD_GLOBAL              1 (True)
             12 COMPARE_OP               2 (==)
             15 RETURN_VALUE        
>>> def check2(x): return bool(x)

>>> dis.dis(check2)
  1           0 LOAD_GLOBAL              0 (bool)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        

Я полагаю, что причина check не оптимизирована в том, что Python является динамическим языком. Само по себе это не означает, что Python использует плохой компилятор, но здесь можно сделать небольшой вывод типа. Может, имеет значение, когда создается файл .pyd?

4
ответ дан 28 November 2019 в 02:41
поделиться

В синтаксисе «boolCheck == true» может быть какое-то обоснование, зависящее от имени проверяемой переменной.

Например, если имя переменной было «состояние» , тогда вы можете иметь:

if (state) {
   ...
}

или

if (state == true) {
   ...
}

В этом случае, я думаю, что последняя форма более ясна и очевидна.

Другим примером может быть переменная, подобная «enabled», и в этом случае первая форма более ясна.

Теперь наличие логической переменной с именем «state» - плохая практика, но вы можете не иметь контроля над тем, в котором случае синтаксис "== true" может улучшить читаемость кода.

2
ответ дан 28 November 2019 в 02:41
поделиться

По моему опыту, if (flag == true) - плохая практика.

Первый аргумент академический:

Если у вас есть bool flag , это либо истина , либо ложь .

Теперь выражение

(flag==true)

снова равно истина или ложь - это не более выразительно, только избыточно - флаг не может быть «более верным» или «более ложным», чем он есть. Было бы «яснее», только если не очевидно, что флаг является логическим, но есть стандартный способ исправить это, который работает для всех типов: выберите лучшее имя .

Если растянуть это без разума, «еще лучше» было бы следующее:

((flag==true)==true)

Второй аргумент является прагматичным и зависящим от платформы.

C и ранние реализации C ++ не имели реального типа "bool", поэтому существуют разные соглашения для флагов, наиболее распространенным из которых является любое ненулевое значение true. API нередко возвращают тип BOOL на основе целых чисел, но не заставляют возвращаемое значение быть 0 или 1.

В некоторых средах используются следующие определения:

#define FALSE 0
#define TRUE (!FALSE)

удачи с if ((1 == 1) == TRUE)

Кроме того, на некоторых платформах используются другие значения - например, VARIANT_BOOL для взаимодействия с VB является коротким , а VARIANT_TRUE - -1 .

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

поэтому существуют разные соглашения для флагов, наиболее распространенным из которых является любое ненулевое значение. API нередко возвращают тип BOOL на основе целых чисел, но не заставляют возвращаемое значение быть 0 или 1.

В некоторых средах используются следующие определения:

#define FALSE 0
#define TRUE (!FALSE)

удачи с if ((1 == 1) == TRUE)

Кроме того, на некоторых платформах используются другие значения - например, VARIANT_BOOL для взаимодействия с VB является коротким , а VARIANT_TRUE - -1 .

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

поэтому существуют разные соглашения для флагов, наиболее распространенным из которых является любое ненулевое значение. API нередко возвращают тип BOOL на основе целых чисел, но не заставляют возвращаемое значение быть 0 или 1.

В некоторых средах используются следующие определения:

#define FALSE 0
#define TRUE (!FALSE)

удачи с if ((1 == 1) == TRUE)

Кроме того, на некоторых платформах используются другие значения - например, VARIANT_BOOL для взаимодействия с VB является коротким , а VARIANT_TRUE - -1 .

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

но не заставлять возвращаемое значение быть 0 или 1.

В некоторых средах используются следующие определения:

#define FALSE 0
#define TRUE (!FALSE)

удачи с if ((1 == 1) == TRUE)

Кроме того, на некоторых платформах используйте другие значения - например, VARIANT_BOOL для взаимодействия с VB является коротким , а VARIANT_TRUE равно -1 .

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

но не заставлять возвращаемое значение быть 0 или 1.

В некоторых средах используются следующие определения:

#define FALSE 0
#define TRUE (!FALSE)

удачи с if ((1 == 1) == TRUE)

Кроме того, на некоторых платформах используйте другие значения - например, VARIANT_BOOL для взаимодействия с VB является коротким , а VARIANT_TRUE равно -1 .

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

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

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

4
ответ дан 28 November 2019 в 02:41
поделиться

Это касается конкретных языков и того, что они считают «правдивыми» значениями. Вот два наиболее распространенных: JavaScript и PHP .

Оператор тройного равенства в обоих этих языках гарантирует, что вы действительно проверяете логический тип истины. Например, в PHP проверка if ($ value) может отличаться от if ($ value == true) или if ($ value === true) :

$f = true;
$z = 1;
$n = null;
$a = array(1,2);

print ($f)        ?'true':'false'; // true
print ($f==true)  ?'true':'false'; // true
print ($f===true) ?'true':'false'; // true
print "\n";
print ($z)        ?'true':'false'; // true
print ($z==true)  ?'true':'false'; // true
print ($z===true) ?'true':'false'; // false
print "\n";
print ($n)        ?'true':'false'; // false
print ($n==true)  ?'true':'false'; // false
print ($n===true) ?'true':'false'; // false
print "\n";
print ($a)        ?'true':'false'; // true
print ($a==true)  ?'true':'false'; // true
print ($a===true) ?'true':'false'; // false
print "\n";
print "\n";

Я ожидаю, что языки, на которых человек говорит ежедневно, повлияют на его отношение к этому вопросу.

2
ответ дан 28 November 2019 в 02:41
поделиться

Проверка на равенство истине может привести к ошибке, по крайней мере, в C: в C, 'if' может использоваться для целочисленных типов (не только для логических типов) и принять любое ненулевое значение; однако символ «ИСТИНА» - это одно конкретное ненулевое значение (например, 1 ). Это может стать важным с битовыми флагами:

if (flags & DCDBIT)
{
    //do something when the DCDBIT bit is set in the flags variable
}

Итак, учитывая такую ​​функцию ...

int isDcdSet()
{
    return (flags & DCDBIT);
}

... выражение «if (isDcdSet ())» не то же самое, что «if (isDcdSet () == ИСТИНА) ".

В любом случае; Я бы подумал, что оптимизирующий компилятор должен оптимизировать любую разницу (потому что нет логической разницы), предполагая, что это '

1
ответ дан 28 November 2019 в 02:41
поделиться

Это может быть не то же самое, если вы работаете с пустым логическим значением.

Пример:

Bool? myBool = true

if(myBool)  // This will not compile

if(myBool == true)  //this will compile
0
ответ дан 28 November 2019 в 02:41
поделиться

Компилятор MSVC ++ 6.0 генерирует немного другой код для двух форм:

4:        if ( ok ) {
00401033   mov         eax,dword ptr [ebp-8]
00401036   and         eax,0FFh
0040103B   test        eax,eax
0040103D   je          main+36h (00401046)
....
7:        if ( ok == true ) {
00401046   mov         ecx,dword ptr [ebp-8]
00401049   and         ecx,0FFh
0040104F   cmp         ecx,1
00401052   jne         main+4Bh (0040105b)

Предыдущая версия должна быть немного быстрее, если я правильно помню свои тайминги 8086: -)

2
ответ дан 28 November 2019 в 02:41
поделиться

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

ifstream fin;
...
if( ! fin)
...
0
ответ дан 28 November 2019 в 02:41
поделиться

Это зависит от компилятора. В любом случае возможны оптимизации.

1
ответ дан 28 November 2019 в 02:41
поделиться

ИМХО, использовать форму if (boolCheck == true) - плохая идея по простой причине: если вы случайно наберете единственный знак «равно» вместо двойной (например, if (boolCheck = true) ), он присвоит true boolCheck и всегда будет возвращать true, что, очевидно, было бы ошибкой. Конечно, большинство современных компиляторов покажут предупреждение, когда увидят это (по крайней мере, компилятор C # это делает), но многие разработчики просто игнорируют предупреждения ...

Если вы хотите быть явным, вам следует предпочесть эту форму: если (true == boolCheck) . Это позволит избежать случайного присвоения переменной и вызовет ошибку компиляции, если вы забудете знак «равно».

0
ответ дан 28 November 2019 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: