Недавно я наткнулся на кусок кода, как это (не реальный, но более короткий пример основывается на него):Оценка ярлыка вместо выполнения выражения if (condition);
#include <stdio.h>
int main()
{
int n;
printf ("n? ");
scanf ("%d", &n);
n%2 && printf ("N is odd\n"); /* <-- this is it */
return 0;
}
В случае, если кто-то не понял, этот код является эквивалент:
int main()
{
int n;
printf ("n? ");
scanf ("%d", &n);
if (n%2)
printf ("N is odd\n");
return 0;
}
разборки этого кода, скомпилированный с GCC 4.4.5-8 для x86-64 бит дает это для той части, в которой n
оценивается и printf()
условно называется:
andl $1, %eax
testb %al, %al
je .L3
movl $.LC2, %eax
movq %rax, %rdi
movl $0, %eax
call printf
testl %eax, %eax
.L3:
movl $0, %eax
leave
ret
Звучит как код, созданный оператором if
. «Стандартный» способ дает это:
andl $1, %eax
testb %al, %al
je .L2
movl $.LC2, %edi
call puts
.L2:
movl $0, %eax
leave
ret
Slighly короче, и немного быстрее, тоже, потому что компилятор может использовать puts()
вместо printf()
, так как он обнаружил, что printf()
используется для печати одной строки, и его возвращаемое значение не используется. Первый пример должен оценить второе выражение после &&
, потому что первый оценивается как истинный, поэтому printf()
должен был использоваться для получения значения для оценки с.
Итак, мой вопрос: может ли этот ярлык для оценки ярлыка считаться хорошим кодированием? Он работает, но ... делает это лучше, чем помогает выиграть конкурс на один лайнер C? Судя по примеру, который я предоставил, я бы сказал «нет», но может ли он быть примером, который доказывает иначе?
ПРИМЕЧАНИЕ: при попытке скомпилировать исходный код компилятор даже сгенерировал ICE (MingW 2.95.2) с текстовой ошибкой, говорящей о «ошибке при выполнении do_jump» или что-то в этом роде.
Это действительно основанный на мнениях вопрос и, следовательно, может быть закрыт. Мое субъективное мнение заключается в том, что версия с использованием '&&' менее понятна, чем просто использовать 'if' для защиты' printf'. Во всяком случае, поэтому многие компании имеют [соглашения о кодировании] (http://en.wikipedia.org/wiki/Coding_conventions), чтобы предотвратить подобные вещи. – DaoWen
Ну, я действительно не ищу субъективных мнений.Мое утверждение состоит в том, что этот трюк, похоже, не полезен, но может существовать пример, который доказывает, что этот трюк работает лучше (используя любую метрику, такую как скорость или размер кода), чем эквивалентный оператор if, и я спрашиваю, знает ли кто-нибудь такой пример (ы). –
Все, что скрывает намерение вашего кода, нельзя считать хорошим кодированием, если у него нет ОГРОМНОЙ окупаемости. (И в этом случае он должен быть задокументирован до смерти.) И даже если бы это было быстрее, большинство машин были достаточно быстрыми, и в наши дни большинство программ достаточно велики, что попытка микро-оптимизации инструкций почти всегда неправильный выбор, если вы не можете * ПРОВЕРИТЬ *, что это критический путь в вашей программе. – keshlam