编程与软件工程yosefk.com
把 C 当作中间语言(2012)
C as an intermediate language (2012)
2013 — 2018,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这篇 2012 年的文章探讨了把 C 当作中间语言来编译其他语言的做法:作者逐项分析动态绑定、垃圾回收、尾调用、异常处理等常见语言特性在 C 上的实现难度,指出哪些容易、哪些会碰壁。文章还回顾了早期 C++ 和 Objective-C 编译器先输出 C 代码的历史。
为什么经久不衰:把 C 作为编译目标至今仍是许多语言(如 Mercury、Eiffel 及各类 DSL)的实际选择,文中对可行性与陷阱的分析对今天设计编译器的人依然有参考价值。
HN 评论精选
实践者证实:编译到 C 在异常处理等特性上代价很高,原生编译器最终胜出
D 语言作者 Walter Bright:我曾考虑把 D 编译到 C,但异常处理、adjustor thunk、C 中未定义/实现定义的行为等问题会耗费太多精力,而且会让编译变慢。另外,我写过 PC 上第一个原生 C++ 编译器,相比基于 cfront 的编译器是巨大进步。
WalterBright查看英文原文
I considered compiling D to C. The trouble is when you need to do things like exception handling, adjustor thunks, define things that are implementation defined or undefined in C, etc. I figured I'd spend too much time struggling with that, and besides, it would make compilation slow. > Without doubt, today the answer is C++ and Objective-C – languages whose first compilers emitted C code. I wrote the first native C++ compiler for the PC. It was a huge win over the cfront based PC compilers, which were nearly unworkable.
Mercury 的实践说明利用 GNU C 扩展可以弥补标准 C 的不足
Mercury 编译器有一个编译到 C 的后端,如今生成“高级”C,代码看起来像 C 程序员写的;早期(90 年代中期)则生成“低级”GNU C,基本像抽象机的汇编。GNU C 的扩展很有用,比如保证尾递归优化、直接访问寄存器和内联汇编,这对函数式语言很关键。
quicklime查看英文原文
The Mercury compiler has a backend which compiles to C. This is currently described as "high-level" C, because the generated code sort-of (relatively speaking) looks like code that a C programmer might write. But back in the early days (mid 90s?) it emitted "low-level" GNU (not ANSI/ISO) C, which basically looked like assembly code for an abstract machine. Kind of like the "compilation strategy" described in TFA, taken a number of steps further. One of the nice things about GNU C is that various GCC-specific extensions can be taken advantage of. For example ISO C does not require a compiler to optimise tail recursive calls, which are heavily used in functional (and logic) programming languages, where recursion is used instead of loops. It also lets you access CPU registers directly, and write inline assembly code.
动态绑定和 GC 在 C 后端上远比想象中难,性能和精度都会受损
文中有些做法没表面那么简单:动态绑定对动态语言来说速度不够,需要多态内联缓存,这要求代码生成器、前端和 IR 紧密配合,C 编译器给不了这种控制力。垃圾回收也有问题:C 编译器无法让运行时找到栈上所有根(区分整数和指针),只能保守扫描或把根全部溢出到栈,两者代价都不小。此外还有尾调用优化和未定义行为等问题。
pcwalton查看英文原文
Some of these aren't as simple as they seem at first glance: > Dynamic binding: easy enough. That technique won't be fast enough for dynamic languages. You really need polymorphic inline caches to make dynamic binding fast, which requires careful cooperation between the code generator, the front end, and the IR. A C compiler won't give you that level of control. > Garbage collection It doesn't work that well. The problem is that C compilers don't provide a way for the runtime to find all roots on the stack (tell apart integers from pointers). You pretty much either have to be conservative on the stack or spill all roots to the stack across function calls. Neither of them is very good: the former costs accuracy and prevents you from using a bump allocator in the nursery, and the latter costs performance. There are other issues to consider as well, for example tail call optimization and undefined behavior.
涉及底层机制(标志位、栈控制)时,编译到 C 会遇到硬性障碍
当你想做 C 处理不好的事情时就会变难,比如操作处理器标志位,或者把控制权交给另一个函数但保持栈不动(objc_msgSend)。如果能插入一些汇编还行,否则就撞墙了。
mpweiher查看英文原文
This becomes difficult when you want to do something that C doesn't really handle (well), for example the processor flags or for example passing control to another function, leaving the stack intact (objc_msgSend). If you can then insert some asm, that's good, otherwise you hit a brick wall. See: https://cr.yp.to/qhasm/20050129-portable.txt
历次讨论
同类还值得读
开源应用架构
The Architecture of Open Source Applications
《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。
编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选编程语言简史:简短、不完整且多半错误
A Brief, Incomplete, and Mostly Wrong History of Programming Languages
一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。
编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.comSQLite 是如何测试的
How SQLite is tested
SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…
编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选高级编程语言(2009)
Advanced programming languages (2009)
Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…
编程与软件工程上首页 8 次 · 2009–2022matt.might.net我的 Forth 与栈机器经历
Yosefk - My history with Forth & stack machines
作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。
编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选