“for(;;)”无限循环的习惯用法是否正确归因于PDP-11 C编译器?

时间:2011-11-28 06:40:24

标签: c++ c compiler-construction history pdp-11

最近,我发现this article声称由于最初在PDP-11上可用的C编译器为for(;;)提供了while(1)而无限循环,因此产生了额外的机器指令{ {1}}。

现在甚至是Visual C ++警告tend to favor the former

while(1)成语的归属有多现实?

6 个答案:

答案 0 :(得分:9)

原始K& R中明确提到“for(;;)”成语。这对我来说足够了:)

答案 1 :(得分:7)

要注意某些“明智的归属”,因为缺乏背景,往往是虚假的秘密。 OP标记了C和C ++的消息。

现在,K& R可能是关于C历史的半神,但肯定不能被认为是C ++的权威。 此外,编译器优化可以在C ++中发挥基本作用,但通常被C系统程序员视为“滥用”(他们喜欢将C视为“带表达式的汇编程序”,而不是“高级语言”)。

今天的编译器很可能产生完全相同的代码(这可以很容易地证明),并且使用其中一个或更多的是品味,然后是其他。

从这个意义上说,我倾向于赞成for(;;),因为我可以轻松地将其视为“ for ever ever ”,而while(true)读作“,而这是真的事情是真的“,让你弄清楚如果它甚至可能是假的...... 2毫秒的脑子浪费了! (但这是个人意见:我知道很多人必须更多地考虑for(;;)而不是while(true)

然而,我也可以将它们都识别为“图形表示​​”(实际上没有阅读文本,只是看看它们通过摄影记忆看起来如何)指向同一个知识概念(留在这里,直到有人会让你离开内侧)。

关于MS警告,有时它会使您免于写错表达式(如true||a)。但是对于没有操作的琐碎表达式,显然是被滥用,并且不应该出现。 Nerveless,MS编译器在两种情况下都生成相同的机器代码。可能对MS的反馈将使他们对未来发布的警告不那么乏味。

答案 2 :(得分:6)

以下是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.cwhile)编译为:

.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.cfor)成为:

.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年,差异已经基本上无关紧要了。

答案 3 :(得分:1)

我不知道这是否属实,但文章声称是明智和现实的。 for(;;)的输入时间比while(1)

答案 4 :(得分:-1)

庵。您可能会发现K& R没有编写PDP-11编译器,因为PDP-11是一台“机器”(不是一种语言),它已经为自己的PDP-11指令集配备了自己的MACRO汇编程序。 p>

K& R {据说'在...中编写了自己的'C'编译器..如果必须是MACRO就不会(因为这是PDP上唯一可用的指令集汇编程序)然后(据称)用'C'编写Unix,因为他们认为它们可以比DEC的PDP-11操作系统(RT-11和RSTS-11)做得更好......而且他们可能是对的!

答案 5 :(得分:-4)

for(;;)是惯用语,所以如果您的代码只能由经验丰富的C程序员阅读,那就太棒了。对于没有经验的程序员和非C程序员来说,while(true)会更容易理解。前者还依赖于一些非显而易见的行为,即空布尔表达式的计算结果为true。出于这些原因,如果你必须选择一个,我会说后者。

然而我认为在几乎所有实际案例中,程序员并不真正希望代码永远循环。你总是有理由想要循环终止,即使只是用户已经命中了control-C。永远不需要无限循环。