此问题参考Reflections on Trusting Trust,图2.
看看这段代码,如图2所示:
...
c = next( );
if(c != '\\')
return(c);
c = next( );
if (c != '\\')
return('\\');
if (c == 'n')
return('\n');
它说:
这是一段了不起的代码。它以完全可移植的方式“知道”为任何字符集中的新行编译的字符代码。知道的行为然后允许它重新编译自己,从而使知识永久化。
我想阅读本文的其余部分。有人可以解释上面的代码是如何重新编译的吗?我不确定我是否理解这段代码与“第1阶段”中的代码有什么关系:
答案 0 :(得分:4)
第2阶段的例子非常有趣,因为它是一个额外的间接级别,具有自我复制程序。
他的意思是,由于这个编译器代码是用C语言编写的,因此它是完全可移植的,因为它检测到文字\ n的存在并返回\ n的字符代码,而不知道自编译器以来实际的字符代码是什么是用C语言编写的,并为系统编译。
本文继续向您展示编译器非常有趣的特洛伊木马。如果你使用同样的技术让编译器在任何程序中插入一个bug,那么删除从源代码中移除bug,编译器会将bug编译成所谓的无bug编译器。
这有点令人困惑,但基本上它是关于多个间接层次的。
答案 1 :(得分:2)
这段代码的作用是翻译转义字符,这是C编译器工作的一部分。
c = next( );
if(c != '\\')
return(c);
此处,如果c
不是\\
(字符\
),则表示它不是转义字符的开头,因此返回自身。
如果是,那么它就是转义字符的开头。
c = next( );
if (c == '\\')
return('\\');
if (c == 'n')
return('\n');
您的问题中有一个拼写错误,它是if (c == '\\')
,而不是if (c != '\\')
。这段代码继续检查\
之后的字符,很明显,如果它是\
,那么整个转义字符是\\
,所以返回它。 \n
也一样。
答案 2 :(得分:1)
Ken Thompson的论文中对该代码的描述是:(强调添加)
图2是解析字符转义序列的 C编译器中的代码的理想化。
所以你正在寻找C编译器的一部分。 C编译器是用C语言编写的,因此它将用于编译自身(或者更准确地说,它是自身的下一个版本)。因此声明代码能够“重新编译自己”。