Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C和它之间的精确关系是什么;什么是抽象机器?_C_Language Lawyer - Fatal编程技术网

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

C和它之间的精确关系是什么;什么是抽象机器?,c,language-lawyer,C,Language Lawyer,我正在读“简而言之C”,有很多类似的句子: 语句指定要执行的一个或多个操作,例如 将值赋给变量,将控制传递给函数,或 跳转到另一个语句 我的问题是,“执行”这些动作的是什么 我到处读到,C被定义为在抽象机器上运行, 所以我的猜测是抽象机器应该执行这些操作,而像gcc这样的实际编译器的工作就是确保 如果你在心理上根据抽象机器的工作方式来评估一个程序,那么你会得到与实际操作相同的结果 运行由编译器生成的目标文件(当然,在大多数情况下,精神上评估程序是不可能的,但我是说 理论上这里) 那么抽象机器应该

我正在读“简而言之C”,有很多类似的句子:

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

我的问题是,“执行”这些动作的是什么

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

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

问题是什么 对程序可见的抽象机器的状态?只有主存储器?如果抽象机器真的直接解释C代码,你会怎么做 声明,它们如何更改抽象机器的状态?最后一系列的问题只是为了给出答案
你可以理解我所说的C和它的抽象机器之间的精确关系。

抽象机器并不存在——毕竟,它是字面上的抽象(“存在于思想中或作为一个想法,但没有物理或具体的存在”)。抽象机器是一个精确遵循标准规则的虚拟机器

C程序由编译器编译到一个具体的机器上,这个机器可能(而且通常确实)具有不同于抽象机器的语义。实际的机器可能具有推测性执行、无序执行和并行性

兼容编译器必须生成一个可执行文件,当运行时,该文件将具有在所述抽象机器中按照标准规则执行的程序的可执行性。

抽象机器是程序执行模型的正式C术语。 它与称为的抽象模型相关,并指的是语言的核心。抽象机器由整个章节C17 5.1.2.3程序执行定义,其中第一行表示:

本国际标准中的语义描述描述了 与优化问题无关的抽象机器

换句话说,抽象机器是程序指定结果的模型,不管优化如何。它指定了表达式的顺序(执行顺序)、确定是否允许优化的规则以及程序的可观察行为

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

举个例子:

int a = 1;
int b = 1;
int c = a + b + 1;
printf("%d", c);
抽象机器指定首先执行
a
b
的初始化,然后执行行
int c=a+b+1最后是printf。结果必须是3。这意味着,如果编译器影响程序的结果,则不允许对这些行重新排序。在
处有序列点,在此之前的所有计算都必须完成

但是,编译器可以自由地首先执行子表达式
a+b
,或者先执行
b+1
,因为它们彼此之间没有顺序。未指定评估顺序。类似地,它可以在
a
之前初始化
b
,因为顺序无关紧要


编译器也可以自由地用
c=1+1+1替换代码或带有
c=3或将其全部替换为
printf(“3”)。两者都不会影响程序的可观察行为,因此进行优化是有效的。

抽象机器什么都不做,实际上也不存在。这就是为什么它被称为抽象机器。Google“c抽象机器”“声明是如何计算的,它们如何更改抽象机器的状态?”-这就是标准中的所有规则所规定的顺序点不指定编译器是否可以对语句重新排序。优化时必须保留可观察的行为。事实上,前两行可以重新排序,可观察的行为不会改变,因此允许编译器重新排序。如果它像你说的那样,即不可能在序列点之间重新排序,即在“;”,编译器就不可能在GUFL优化中做任何有意义的事情。@ad3Angel1我在哪里说过这些?“这意味着如果编译器影响程序的结果,则不允许对这些行重新排序”,这反过来意味着如果编译器不影响程序的结果,则允许对这些行重新排序。此处:“这意味着,如果影响程序的结果,编译器不允许对这些行重新排序。在第二层有序列点;必须完成之前所有计算的每一行。“序列点上的部分充其量也不清楚。这意味着如果您首先拥有行
a=a+b之后是
c=a+b,编译器不允许放置
c=a+b计算高于第一个,因为它会改变代码的含义。这正是序列点的目的。