2014-07-21 3 views
1

Ради удобства чтения, я хотел бы написать логические условия «в полном объеме» в C/C++, например .:Выполняет ли запись логических условий «в полном» компромиссном исполнении?

if (foo == true) вместо if (foo)if (foo == false) и вместо if (!foo).

Выполняет ли это компромиссное исполнение?

+7

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

+7

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

+0

@MikeSeymour и @DanielDaranas: Хорошо, я всегда готов изменить свои практики, если они не самые лучшие. Не могли бы вы объяснить, почему вы считаете 'if (! Foo)' более легким для чтения, чем 'if (foo == false)'? Я нахожу это! довольно склонны к тому, чтобы их не замечали. – MGA

ответ

2

Что касается прямой С, то, что две формы могут результат в другой машинный код, который может влиять на производительность. Является ли эта разница в производительности вопросами будет зависеть от того, что делает код и каковы ваши требования к производительности.

Использование gcc 4.1.2 на SLES 10, я получаю немного другой машинный код для if (foo == false) vs if (!foo); учитывая следующий исходный код:

if (foo == false) 
{ 
    printf("foo is false\n"); 
} 

if (!foo) 
{ 
    printf("foo is 0\n"); 
} 

Я получаю код следующие машины (gcc -S -std=c99 -pedantic -Wall -Werror):

 movb $0, -1(%rbp)  ;; foo = false 
     cmpb $0, -1(%rbp)  ;; if (foo == false) 
     jne  .L6    ;; { 
     movl $.LC2, %edi  ;; 
     call puts    ;; printf("foo is false\n"); 
.L6:        ;; } 
     movzbl -1(%rbp), %eax ;; if (!foo) 
     xorl $1, %eax 
     testb %al, %al 
     je  .L8    ;; { 
     movl $.LC3, %edi  ;; 
     call puts    ;; printf("foo is 0\n"); 
.L8:        ;; } 
     movl $0, %eax 

Для этой конкретной платформы, компилятор, код, и набор опций компилятора, if (!foo) может наматывать немного ниже, чем if (foo == false) .

Теперь, для настоящего вопроса: имеет ли это различие в производительности (если оно существует)? Для этой конкретной программы абсолютно нет; тест выполняется один раз в течение срока действия программы, а время, затрачиваемое на ввод-вывод, будет значительно больше времени, затрачиваемого на выполнение теста. В другой программе, где этот тест выполняется тысячи или миллионы раз в узком цикле, который связан с CPU, тогда это может иметь значение совсем немного.

Код для читаемости первый; формы if (foo) и if (!foo), как правило, являются идиоматическими для простых булевых тестов, и это ожидают увидеть большинство программистов на C и C++. Сказав это, нет абсолютно ничего плохого в написании if (foo == TRUE) и if (foo == FALSE), если вы считаете, что оно лучше передает код кода (или если вы решите определить TRUE как 0 и FALSE как 1 по какой-либо причине).

Но не принимать это решение на основе производительности если:

  1. Вы не в состоянии удовлетворить требования жесткого исполнения;
  2. Вы оптимизировали свой алгоритм и структуры данных соответствующим образом; и
  3. Профилирование показывает , что конкретное заявление является остающимся узким местом.


1. Или нет; это зависит от того, сколько циклов xorl и testb требуют vs cmpb и насколько быстрее это регистр доступа %eax непосредственно, чем для вычисления -1(%rbp) и доступа к полученному местоположению; для всех, кого я знаю, это мойка.

3

Предполагая, что foo - это bool, это не так. Компилятор может быть оптимизирован тривиально.

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

+1

Теперь это было бы весело. Перегрузите как 'operator!', Так и 'operator == (bool)', с несвязанной семантикой. (Но я предполагал, что он говорил о 'foo' типа' bool'.) –

+0

Спасибо. Мне интересно узнать, почему существует необходимость в оптимизации компилятором, если 'foo' является bool? – MGA

+2

@JamesKanze: Много удовольствия будет у всех, желающих забросить все условности и здравого смысла ... – Deduplicator

-4

Предполагая, что foo - это bool, это не так. Компилятор может быть оптимизирован тривиально.

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

+3

Почему вы только что скопировали ответ @ neilkirk verbatim? – juanchopanza

+1

Скопировано из @ Neil-Kirk. – MGA

+1

Голосование для удаления. – Caleb

1
if(foo == true) 

Даже если со злом перегружает он может иметь различную семантику и эксплуатационные характеристики, чем более идиоматических потому менее многословным

if(! foo) 

, Жека здравомыслящих типов и достаточно эффективных компиляторов, она должна производить именно такие же нативные инструкции.

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

Тем не менее, вышеизложенное не является каноническим примером глупости всегда добавляя явное сравнение.
Это было бы:

if(foo) 
if(foo == true) 
if((foo == true) == true) 
// ... 

К недостаткам можно отнести:

  • Излишне многословие, не разъясняющие ничего.
  • Опасность забыть один = -знак, поэтому стараемся присвоить значение.
  • Насколько «прояснение» будет достаточно ясным?
  • Если не использовать ключевые слова для булевых констант, но лежащие в основе 0 и 1, то это сравнение рисков для равенства 1, где требуется неравенство 0.

Следует иметь в виду, что в языках C, C++ и некоторых родственных языках это относится и к указателям, целым числам (включая типы символов) и большинству пользовательских типов.

 Смежные вопросы

  • Нет связанных вопросов^_^