我有以下代码:
#include <cstdio>
int main()
{
if ((1.0 + 0.1) != (1.0 + 0.1))
printf("not equal\n");
else
printf("equal\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当使用gcc(4.4,4.5和4.6)使用O3编译并本机运行(ubuntu 10.10)时,它会打印预期的"相等"结果.
但是,当如上所述编译并在虚拟机(ubuntu 10.10,virtualbox image)上运行时,它输出"不相等"的情况下相同的代码 - 这是O3和O2标志设置但不是O1及以下时的情况.当使用clang(O3和O2)编译并在虚拟机上运行时,我得到了正确的结果.
我理解1.1无法使用double正确表示,我读过"每个计算机科学家应该知道浮点算术的内容"所以请不要指向我那里,这似乎是GCC做的某种优化不知何故似乎在虚拟机中不起作用.
有任何想法吗?
注意:C++标准说在这种情况下类型提升是依赖于实现的,可能是GCC使用更精确的内部表示,当应用不等式测试时,它是否成立 - 由于额外的精度?
UPDATE1:以上修改上面的代码,现在得到了正确的结果.在某些时候,无论出于何种原因,GCC都会关闭浮点控制字.
#include <cstdio>
void set_dpfpu() { unsigned int mode = 0x27F; asm ("fldcw %0" : : "m" (*&mode));
int main()
{
set_dpfpu();
if ((1.0 + 0.1) != (1.0 + 0.1))
printf("not equal\n");
else
printf("equal\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
UPDATE2:对于那些询问代码的const表达性质的人,我已经改变了如下,并且在使用GCC编译时仍然失败. - 但我认为优化器也可能将以下内容转换为const表达式.
#include <cstdio>
void …Run Code Online (Sandbox Code Playgroud) c++ compiler-construction optimization double-precision vm-implementation
刚刚看过谷歌宣布新网络编程语言Dart的早期预览的消息.dartlang.org上的文档说明:
您将能够以多种方式运行Dart代码:
将Dart代码转换为可在任何现代浏览器中运行的JavaScript:Chrome,Safari 5+和Firefox 4+(不久将提供更多浏览器支持).
直接在服务器端的VM中执行Dart代码
使用Dartboard在任何浏览器窗口中编写,修改和执行小型Dart程序
我很好奇是否已有VM可用于运行Dart代码?无论如何都找不到它,也许它可以通过一些beta程序获得?
我一直在研究编程语言是如何工作的,其中一些有一个所谓的虚拟机.我知道这是在另一种编程语言中对编程语言进行仿真的某种形式,并且它的工作方式与使用堆栈执行编译语言的方式相同.我做对了吗?
根据我所做的附带条件,让我感到困惑的是,许多非编译语言允许使用"自由"类型系统的变量.以Python为例,我可以这样写:
x = "Hello world!"
x = 2**1000
Run Code Online (Sandbox Code Playgroud)
字符串和大整数是完全不相关的,并且在内存中占用不同的空间,那么这个代码如何在基于堆栈的环境中表示?这到底发生了什么?x是否指向堆栈中的新位置并且旧的字符串数据未被引用?这些语言不使用堆栈吗?如果没有,它们如何在内部表示变量?
我目前正在Android平台上撰写论文.经过一番研究,很明显Dalvik还有改进的余地.我想知道,你觉得开发人员在这个目标上的最佳用途是什么?
JIT编译似乎是一个很大的问题,但后来我也听说过这种资源在这么低资源的机器上使用有限.有没有人有资源或数据支持这一点?
是否还有其他选择需要考虑?除了开发强大的本机开发工具包以绕过VM.
对于那些感兴趣的人,有一个关于Dalvik VM的录音和在线讲座.
任何想法都欢迎,因为这个问题似乎是主观的,我会澄清我接受的答案必须有一些理由提出修改.任何支持它的数据,例如Sun JVM引入时的改进,都将是一个巨大的优势.
是否有用纯 Python 编写的JavaScript(ECMAScript)实现?即使它的实现非常缓慢也没关系.
我为C编写了一个输出字节代码的编译器.这样做的原因是能够为在多个平台上运行的嵌入式平台编写应用程序.
我有编译器和汇编程序.
我需要编写一个链接器,并且卡住了.
对象格式是一个自定义格式,围绕字节码解释器设计,所以我真的不能使用任何现有的链接器.
我最大的障碍是如何组织目标代码以输出链接的二进制文件.此时不需要动态链接.我需要先让静态链接工作.
c compiler-construction linker interpreter vm-implementation
作为辅助项目的背景,我一直在阅读有关不同虚拟机设计的内容,其中JVM当然获得了最多的新闻.我还看了BEAM(Erlang),GHC的RTS(有点但不是很简单的VM)和一些JavaScript实现.Python也有一个字节码解释器,我知道存在,但没有读太多.
我没有找到的是一个很好的解释为什么为特定语言选择特定的虚拟机设计.我对那些适合并发和/或非常动态(Ruby,JavaScript,Lisp)语言的设计选择特别感兴趣.
编辑:在回答要求特异性的评论时,这是一个例子.JVM使用堆栈计算机而不是寄存器计算机,这在Java首次引入时非常有争议.事实证明,设计JVM的工程师已经完成了这样的平台可移植性,并且将堆栈机器转换回寄存器机器比克服虚拟寄存器太多或太少的阻抗不匹配更容易,更有效.
这是另一个例子:对于Haskell,要查看的论文是在库存硬件上实现懒惰的函数式语言:Spineless Tagless G-machine.这与我所知道的任何其他类型的VM非常不同.事实上GHC(Haskell的首要实现)并不是实时运行,而是用作编译的中间步骤.Peyton-Jones列出了不少于8个其他无效的虚拟机.我想了解为什么有些VM会在其他失败的情况下成功.
我正在研究用C编写的简单堆栈机器,主要用于学习目的.在malloc/free用于我的内存操作后,我认为从现代虚拟机中读取一些特定于内存分配的代码是个好主意.
我下载了Lua源代码并开始阅读它.过了一会儿,我意识到涉及很多宏的东西,我找不到真正的内存分配完成的代码(即malloc调用).
find . -exec grep -i "malloc" '{}' \; -print
Run Code Online (Sandbox Code Playgroud)
它只打印了一些malloc名字中包含单词的Lua宏.Lua VM(和编程语言)根本不使用malloc!
所以这引出了一个问题:现代虚拟机如何处理内存分配?Lua如何从堆中分配内存?除了以外有什么方法可以分配malloc吗?其他方法的优缺点是什么?
我也想知道安全地处理分配的内存的最佳实践,设计模式等.我在Lua的源代码中看到,在分配内存之前有很多间接.我在哪里可以了解这些东西?
BEAM和JVM之间的一些基本功能/架构差异是什么?
我正在设计一种编译语言,编译成中间字节码.但是,我在设计字节码结构时遇到了很多麻烦.有没有人对如何用二进制表示程序有任何指示?或者,是否有任何资源(最好是免费的)如何做到这一点?我发现的最接近的是Lua解释器的字节码的描述.
编辑:更多信息:我正在实现我自己的垃圾收集方案,该方案针对不可变性和并发性进行了大量优化.为了提高效率,我需要一些独特的字节码指令,允许程序与垃圾收集方案进行交互.
interpreter ×3
c ×2
jvm ×2
android ×1
architecture ×1
beam ×1
bytecode ×1
c++ ×1
dalvik ×1
dart ×1
erlang ×1
javascript ×1
jit ×1
linker ×1
lua ×1
optimization ×1
python ×1
runtime ×1
stack ×1