首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回中的Post-Increment :它们是如何实现的?

返回中的Post-Increment :它们是如何实现的?
EN

Stack Overflow用户
提问于 2013-03-17 19:22:49
回答 3查看 252关注 0票数 0

因此,我知道许多C风格的语言都有减量(--)和递增(++)运算符,并允许在整个表达式求值之前或之后发生突变。

当返回值发生后增量时会发生什么?我不是在问行为,而是问实现。

给定一个虚拟机(如JavaScript/JVM)或物理机(如编译的C++),生成的操作码是否如下所示?(假设基于堆栈的参数/返回。)

代码语言:javascript
复制
int x = 4, y = 8;
return f(++a) + y++;

变成这样:(也许?)

代码语言:javascript
复制
LOAD 4 A
LOAD 8 B

INC A
PUSH A
CALL F
POP INTO C
ADD C BY B
INC B
RET C

如果是这样的话,当表达式变得复杂时,这些语言中的这些操作如何决定在哪里嵌入增量?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-17 19:42:50

一旦优化了代码(通过C++编译器或JIT),我希望得到类似于以下内容的结果:

来源:

代码语言:javascript
复制
int x = 4, y = 8;
return f(++x) + y++;

使用说明:

代码语言:javascript
复制
PUSH 5
CALL f
POP INTO A
ADD 8 to A
RET A

我列出的指令是正确的(除非我犯了一些愚蠢的错误),它们只需要我知道优化器能够进行的代码转换。基本上,不计算未使用的结果,而在优化时计算具有已知结果的操作。

在特定的体系结构上,很可能有一种更有效的方法来实现它,在这种情况下,优化器很有可能知道并使用它。优化器经常超出我的预期,因为我不是一个专业的汇编程序员。在这种情况下,调用约定很可能为函数f和以下代码中的返回值指定了相同的位置。因此,可能不需要任何POP --返回寄存器/堆栈位置可以只添加8。此外,如果函数f是内联的,那么优化将在内联之后应用。

例如,如果f返回input * 2,那么整个函数可能会优化为:

代码语言:javascript
复制
RET 18
票数 2
EN

Stack Overflow用户

发布于 2013-03-17 19:28:22

Java运行时与您的源代码甚至字节码相去甚远。一旦对一个方法进行了JIT编译,得到的机器码就会得到积极的优化。但更重要的是,这种优化的细节远远超出了任何规范。如果您对它感兴趣,您可能会深入研究像HotSpot这样的实现,但您从中学到的所有东西都是特定于平台、版本、内部版本号、JVM启动参数,甚至是JVM的单独运行。

票数 3
EN

Stack Overflow用户

发布于 2013-03-17 19:46:02

您可以确切地看到编译器使用javap生成的内容。例如:

代码语言:javascript
复制
int x = 4, y = 8;
return f(++x) + y++;

被编译成这个字节码序列:

代码语言:javascript
复制
0:  iconst_4
1:  istore_1
2:  bipush  8
4:  istore_2
5:  aload_0
6:  iinc    1, 1
9:  iload_1
10: invokevirtual   #2; //Method f:(I)I
13: iload_2
14: iinc    2, 1
17: iadd
18: ireturn

当然,这取决于JVM如何将其转换为汇编程序-有关如何在OpenJDK 7中查看结果的信息,请参阅Disassemble Java JIT compiled native bytecode

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15460199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档