10

最近我发现这篇文章声称,之所以选择for(;;)使用while(1)无限循环,是因为最初在 PDP-11 上可用的 C 编译器为while(1).

顺便说一句,现在甚至 Visual C++ 警告也倾向于前者

for(;;)这种成语的归属有多现实?

4

6 回答 6

10

"for(;;)" 成语在原始 K&R 中明确提及。这对我来说已经足够了:)

于 2011-11-28T06:43:26.137 回答
7

谨防某些“明智的归因”,因为缺乏上下文,往往是虚假神话的来源。OP 将消息标记为 C 和 C++。

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

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

从这个意义上说,我倾向于赞成for(;;),因为我可以很容易地把它读成“永远”,而while(true)读成“虽然这个真实的东西是真的”,让你想知道它怎么可能是假的……。浪费了2毫秒的大脑!(但这是个人意见:我知道很多人必须考虑for(;;)比更多while(true)

但是,我也可以将它们都识别为“图像表示”(无需实际阅读文本,只是通过照片记忆查看它们的外观)指向相同的知识概念(待在这里,直到有人将您从内部踢开)。

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

于 2011-11-28T07:49:25.950 回答
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.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 年,这种差异已经在很大程度上无关紧要了。

于 2011-11-28T13:19:52.693 回答
1

我不知道这是否属实,但文章声称是明智和现实的。并且for(;;)比打字更短while(1)

于 2011-11-28T06:44:06.807 回答
-1

嗯。认为您会发现 K&R 没有编写 PDP-11 编译器,因为 PDP-11 是一种“机器”(不是一种语言),它已经为自己的 PDP-11 指令集拥有自己的 MACRO 汇编程序。

K&R(据说)用......写了他们自己的“C”编译器……好吧..如果必须是 MACRO 不是吗(因为那是 PDP 上唯一可用的指令集汇编器)然后(据说)编写了 Unix在“C”中,因为他们认为他们可以比 DEC 的 PDP-11 操作系统(RT-11 和 RSTS-11)做得更好......他们可能是对的!

于 2012-12-28T16:40:59.433 回答
-4

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

但是我会争辩说,在几乎所有真实情况下,程序员并不真的希望代码永远循环。您可能希望循环终止总是有原因的,即使只是用户按下了 control-C。永远不需要无限循环。

于 2011-11-28T10:30:49.790 回答