繁体   English   中英

这是编译器编译的顺序

[英]which is the order that a compiler compiles

好吧,我想知道编译器“读取”代码的顺序是哪一个。 例如:

假设我有以下代码片段:

int N, M;

N = M = 0;

在这种情况下,编译器将为N和M分配内存的一部分(int,4个字节),然后在第二行(我怀疑的地方)分配两个东西,一个:

编译器“读”N等于M并等于零。

要么

编译器“读取”零,将其放入M的内存中,然后获取M的值,即零,并将其置于N的内存中。

换句话说,它是从右到左,还是从左到右?

我不知道我是否明白我的怀疑,但在我做的测试中:

int i=0; /*I declared the variable i, and assign zero value to it*/

printf("%d", i++); /*Prints 0*/

printf("%d", i); /*Prints 1*/

我理解上面的代码,在第二行,编译器似乎(从我的不好)从左到右“读取”,分配类型%d的i值,并且在打印之后,变量i递增,因为在第三行打印为1。

下面的代码片段反转了++的位置:

int i=0; /*I declared i variable to zero*/

printf("%d", ++i); /*Prints 1*/

printf("%d", i); /*Prints 1*/

在这种情况下,在第二行,(从我的理解),编译器从左到右“读取”,当编译器读取将要打印的内容(保留在逗号后面,这个空间的名称是什么?) ,首先“读取”++并在下面增加变量,在这种情况下是i,然后分配给%d进行打印。

按顺序,这是编译器“读取”的顺序? 我有一些老师告诉我编译器从右到左“读”,从分号(;),但编译器实际上有一个命令? 如果我上面说的是错的,请纠正我。(我不会说英语很好)

谢谢!

只有lexical anaylizer从左到右读取源代码。 语法分析器构建AST并以各种方式读取它们,具体取决于它找到的特定节点。

对于表达式,保持表达式的AST可以按顺序读取,以生成后缀表达式,更适合于基于堆栈的求值程序(最容易实现)。

对于赋值(确实是表达式),AST首先读取并生成代码,然后为LHS生成代码,然后生成写入到内存的指令。

对于函数调用,可以从包含参数表达式的最后一个节点解析AST到第一个节点(如果使用C调用约定来执行调用)。

I understand the above code, at the second line, the compiler seems(from what i undestood)"read" from left to right, assigning to the type %d the i value, and after print, the variable i is incremented, because at the third line it is printed as 1.

这不是事情的顺序。

当你调用i ++时,i增加1.然后返回增量发生前的值。

所以你的: printf("%d", i++)

实际上是在做:

int i = somevalue;
int temp = i;
i = i + 1;
printf("%d", temp);

打印后我没有增加。 它实际上是在打印之前。

当你这样做: printf("%d", ++i)

它确实:

int i = somevalue;
i = i + 1;
printf("%d", i);

差异是临时变量。 在这种情况下,你的老师是正确的,它是从分号从右到左的,因为:

它必须首先处理我的价值。 然后它可以打印出来。 实际上,如果你按照每个操作或指令将它全部分解为一个单独的行,它实际上是从上到下,如上所示。

根据C ++标准(和C标准)

赋值运算符(=)和复合赋值运算符都是从右到左分组。

所以在这个声明中

N = M = 0;

编译器指定0到M并且符合标准

返回一个引用左操作数的左值

这是在你的例子0中,在tuen被分配给N.

对于经验证据,我编译:int M,N; N = M = 0;

没有编译器选项,在我的Mac上并反汇编它:

0000000100000f10    pushq   %rbp
0000000100000f11    movq    %rsp,%rbp
0000000100000f14    movl    %edi,0xfc(%rbp)
0000000100000f17    movq    %rsi,0xf0(%rbp)
0000000100000f1b    movl    $0x00000000,0xe4(%rbp)
0000000100000f22    movl    0xe4(%rbp),%eax
0000000100000f25    movl    %eax,0xe0(%rbp)
0000000100000f28    movl    $0x00000000,0xe8(%rbp)
0000000100000f2f    movl    0xe8(%rbp),%eax
0000000100000f32    movl    %eax,0xec(%rbp)
0000000100000f35    movl    0xec(%rbp),%eax
0000000100000f38    popq    %rbp
0000000100000f39    ret

所以看起来编译器决定将其编译为:N = 0; M = 0;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM