В любом нормальном компиляторе не должно быть абсолютно никакой разницы. Например, вот что генерирует LLVM-clang
(с флагом -O3
) для while (1) {}
:
.file "test.c"
.text
.globl main
.align 16, 0x90
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
.align 16, 0x90
.LBB0_1:
jmp .LBB0_1
Обратите внимание на jmp .LBB0_1
часть, которая является фактическим бесконечным циклом. Для типа для вида (;;)
он генерирует абсолютно такой же код .
Вы также можете попробовать с другими компиляторами для развлечения, но лучше просто не беспокоиться об этом.
Хорошо, мне просто пришлось попробовать gcc
:
.file "test.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
.L2:
jmp .L2
Я предпочитаю вместо (;;)
, потому что он ничего не проверяет и семантически это то, что вы имеете в виду. Нет особого смысла продолжать тестирование, истинно ли 1. Однако любой профессиональный программист на C должен сразу распознать обе идиомы, поскольку они используются.
С точки зрения реальной производительности разницы быть не должно. Компилятор оптимизирует тест.
Я попробовал протестировать оба, чтобы увидеть, что быстрее, но ни один из них еще не завершился.
Я бы сказал, что ни один из них не более оптимизирован, поскольку ни один из них не справится с задачей зацикливания бесконечно за любой измеримый промежуток времени.
Действительно ли возможно достичь бесконечности более или менее эффективно?
Теоретически полностью наивный компилятор может хранить буквальную «1» в двоичном коде (тратя пространство) и проверять, равно ли 1 == 0 на каждой итерации (тратя время и больше места).
В действительности, однако, даже без оптимизаций, компиляторы все равно сводят оба значения к одному и тому же. Они также могут выдавать предупреждения, поскольку это может указывать на логическую ошибку. Например, аргумент while может быть определен где-то еще, и вы не понимаете, что он постоянный.
Это мое мнение (исследования не проводились):
При отладке кода, когда я прохожу через него, for циклы заставляют меня сначала переходить ко всем трем частям, а затем к двум. остальные итерации. Однако цикл while имеет только один. Просто мысль.
То же самое. компилятор преобразует его в одну инструкцию JMP.