Правильно ли относится идиома for (;;) для бесконечного цикла к компилятору PDP-11 C? - PullRequest
10 голосов
/ 28 ноября 2011

Недавно я обнаружил эту статью , в которой утверждается, что идея предпочесть for(;;) над while(1) для бесконечного цикла пришла, потому что компилятор C, изначально доступный на PDP-11, сгенерировал дополнительную машинную инструкцию для while(1).

Кстати, даже предупреждения Visual C ++ имеют тенденцию отдавать предпочтение прежним .

Насколько реалистична такая атрибуция for(;;) идиома?

Ответы [ 6 ]

9 голосов
/ 28 ноября 2011

Идиома «for (;;)» явно упоминается в оригинальном K & R. Этого достаточно для атрибуции:)

7 голосов
/ 28 ноября 2011

Остерегайтесь определенной «разумной атрибуции», потому что из-за отсутствия контекста часто являются источниками ложного мифа.ОП пометил сообщение как C, так и C ++.

Теперь K & R могут быть полубогами об истории C, но, безусловно, не могут считаться авторитетом в C ++.Кроме того, оптимизация компилятора может играть фундаментальную роль в C ++, но часто рассматривается программистами системы C как «оскорбительная» (им нравится рассматривать C как «Ассемблер с выражениями», а не как «язык высокого уровня»).

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

В этом смысле я склоняюсь к предпочтению for(;;), потому что я легко могу прочитать его как " навсегда ", в то время как while(true) читается как ", в то время как эта истинная вещь истинна ", заставляя вас понять, как, если это даже может быть ложным ...2 месяца мозга впустую!(Но это личное мнение: я знаю многих людей, которые должны больше думать о for(;;), чем while(true))

Однако я также могу распознать их обоих как «изобразительное представление» (фактически не читаятекст, просто смотря, как они выглядят через фотографическую память), указывающий на ту же интеллектуальную концепцию (оставайтесь здесь, пока кто-то не выгонит вас изнутри).

О предупреждении MS, иногда оно спасает вас от плохо написанноговыражения (например, true||a).Но явно злоупотребляет, и не должно появляться, для тривиальных выражений без операции внутри.В обоих случаях компилятор MS выдает одинаковый машинный код.Возможно, обратная связь с MS сделает их менее утомительными по поводу этого предупреждения в будущих выпусках.

6 голосов
/ 28 ноября 2011

Вот что производит компилятор V7 Unix cc (используя SIMH и изображение из TUHS ):

$ cat>a.c
main(){
 while(1);
}
$ cat>b.c
main(){
 for(;;);
}
$ cc -S a.c
$ cc -S b.c

a.c (while) компилируется в:

.globl  _main
.text
_main:
~~main:
jsr     r5,csv
jbr     L1
L2:L4:tst       $1
jeq     L5
jbr     L4
L5:L3:jmp       cret
L1:jbr  L2
.globl
.data

В то время как b.c (for) становится:

.globl  _main
.text
_main:
~~main:
jsr     r5,csv
jbr     L1
L2:L4:jbr       L4
L5:L3:jmp       cret
L1:jbr  L2
.globl
.data

Так что по крайней мере верно, что for(;;) скомпилировано с меньшим количеством инструкций, когда не используетсяоптимизация.Однако при компиляции с -O обе программы выдают точно одинаковую сборку:

.globl  _main
.text
_main:
~~main:
jsr     r5,csv
L4:jbr  L4
.globl
.data

, и когда я добавляю тело цикла printf("Hello");, программы остаются прежними.

Таким образом, возможно, что идиома берет свое начало в машинном языке PDP-11, но к 1979 году эта разница уже была в значительной степени неактуальной.

1 голос
/ 28 ноября 2011

Я не знаю, правда ли это, но утверждение статьи разумно и реалистично.И for(;;) короче типа while(1)

0 голосов
/ 28 декабря 2012

Um. Думаю, вы обнаружите, что K & R не писал компилятор PDP-11, поскольку PDP-11 был «машиной» (а не языком), у которого уже был собственный MACRO Assembler для собственного набора инструкций PDP-11.

K & R (по общему мнению) написал свой собственный компилятор 'C' в ... ну ... если бы это был MACRO, не так ли (так как это был единственный набор ассемблеров, доступный на PDP), а затем (по общему мнению) ) написали Unix на «С», так как думали, что могут работать лучше, чем операционные системы DEC PDP-11 (RT-11 и RSTS-11) .. и они, вероятно, были правы!

0 голосов
/ 28 ноября 2011

for(;;) идиоматичен, поэтому здорово, что ваш код будет когда-либо читаться только опытными программистами Си.while(true) будет более понятным для неопытных программистов и не программистов на Си.Первое также опирается на некоторое неочевидное поведение, а именно, что пустое логическое выражение оценивается как true.По этой причине, если вы должны выбрать один, я бы сказал, пойти на второй.

Однако Я бы сказал, что практически во всех реальных случаях программист на самом деле не хочет кодзациклить навсегда.Всегда есть причина, по которой вы можете захотеть завершить цикл, даже если пользователь просто нажал control-C.Нет необходимости в бесконечном цикле.

...