C和它的抽象机器之间的确切关系是什么?

0 c language-lawyer

我正在读"C简而言之",并且有很多与此类似的句子:

语句指定要执行的一个或多个操作,例如为变量赋值,将控制传递给函数或跳转到另一个语句.

我的问题是"执行"这些行为的是什么?

我已经在这里和那里读过C被定义为在抽象机器上运行,所以我的猜测是抽象机器应该执行这些操作,而像gcc这样的实际编译器的工作是确保如果你在精神上评估一个程序基于抽象机器的工作方式,你会得到与实际运行编译器生成的目标文件时相同的结果(在大多数情况下,在心理上评估程序是不可能的,但我在理论上讲这里).

抽象机器应该直接解释C代码(在预处理之后)吗?C应该被翻译成抽象机器解释的一些中间代码吗?抽象机器和C之间究竟有什么关系?

程序可见的抽象机的状态是什么?只有主存?如果抽象机器直接解释C代码,如何评估声明,它们如何改变抽象机器的状态?最后一系列问题只是为了让您了解C与它的抽象机器之间的精确关系是什么意思.

Ant*_*ala 7

抽象机器不存在 - 毕竟,它实际上是抽象的("存在于思想中或作为一个想法,但没有物理或具体的存在").抽象机是一个虚构的机器,严格遵循标准的规则.

C程序由编译器编译到具体机器上,该机器可能(通常确实)具有与抽象机器不同的语义.实际的机器可能有推测执行,乱序执行和并行等.

兼容的编译器必须生成一个可执行文件,该文件在运行时将具有可观察的行为 ,就好像该程序是在遵循标准规则的所述抽象机器中执行的.


Lun*_*din 6

抽象机是一个正式的C项程序执行的模式.它与名为图灵机的抽象模型有关,并且是指该语言的核心.抽象机器由整个章节C17 5.1.2.3程序执行定义,其中第一行表示:

本国际标准中的语义描述描述了抽象机器的行为,其中优化问题是无关紧要的.

换句话说,抽象机器是程序指定结果的模型,无论优化如何.它指定该术语测序表达式(执行顺序),用于确定是否优化被允许或不和规则可观察到的行为的程序.

非常简单地说,抽象机器指定要读取源代码行,就好像从源文件的顶部到底部执行一样.

举个例子:

int a = 1;
int b = 1;
int c = a + b + 1;
printf("%d", c);
Run Code Online (Sandbox Code Playgroud)

抽象机器指定首先执行a和初始化b,然后执行行int c = a + b + 1;,最后执行printf.结果必须为3.这意味着如果编译器影响程序的结果,则不允许编译器重新排序这些行.有序列点;每一行,所有以前的计算必须完成的.

然而,编译器可以a + b首先或 b + 1首先执行子表达式,因为它们不是相对于彼此排序的.未指定评估顺序.同样,它可以在订单无关紧要b之前进行初始化a.

编译器也可以随意替换代码c = 1 + 1 + 1;,c = 3;或者只是替换代码printf("3");.两者都不会影响程序的可观察行为,因此这将是有效的优化.