编程语言与软件工程2016complang.tuwien.ac.at
编译器作者应该了解的关于程序员的知识
What every compiler writer should know about programmers
进阶 · 约 30 分钟读完前置知识:C 语言、未定义行为、编译器优化基础
导读
这篇论文批评现代 C 编译器(尤其是 GCC 和 Clang)过于激进地利用未定义行为进行优化,导致程序员认为正确的代码被意外破坏,并呼吁编译器作者更重视程序员的实际预期和代码意图。评论者对此看法分歧:有人认同观点但批评论文语气,也有人从 C 标准、经济现实和具体代码例子出发为编译器辩护。
HN 关注点:编译器优化与未定义行为之间的长期紧张关系,以及论文对 GCC/Clang 维护者的尖锐批评是否公允、是否有证据支持。
HN 评论精选
这几条评论里:质疑 3 亲历 1
质疑质疑论文对 GCC/Clang 维护者的指控缺乏邮件列表证据,认为作者混淆了 C 委员会与编译器作者的责任。
这位作者忽略了一点:许多未定义行为是明确留给编译器作者去利用的。所以他真正该争论的是 C 委员会没有按他想要的方式定义这些行为。他声称“应该发生什么”显而易见,这很奇怪(比如“编译器应该做它正试图证明不会发生的事”)。这基本上是在抱怨编译器作者没有遵循他脑中的 C 精神。(另外,他态度也挺混蛋的。)我读到他说“我们曾计划把这个优化变成生产特性,但最终意识到 GCC 维护者只关心某些基准测试,把生产程序员当作敌人,活该代码被破坏……当前的 GCC 和 Clang 维护者建议我们把程序转成 C。这对 Gforth 会怎样?”我很好奇,就去找 GCC 或 Clang 邮件列表里有人建议过这个或发生过这些事的讨论。两边的邮件列表我都找不到。我搜了 gforth、anton 等等,什么都没有。
DannyBee查看英文原文
One of the things this person misses is a lot of these are undefined with the explicit goal to let compiler authors take advantage of them. So his real argument is with the C committee for not defining these things the way he wants them. His claim that the behavior of what should happen is obvious is pretty strange (IE "it should do exactly whatever the compiler is trying to prove it doesn't") It's essentially a complaint that compiler authors should follow a mystical spirit of C that he seems to have in his head. (Plus, you know, he's kind of a dick about it all) I read things like "We had plans to turn this optimization into a production feature, but eventually realized that the GCC maintainers only care about certain benchmarks and treat production programmers as adversaries that deserve getting their code broken. ... The current GCC and Clang maintainers suggest that we should convert programs to “C”. How would that turn out for Gforth?" I was intrigued, so i went looking for the mailing list discussion where the gcc or clang people suggested this or where any of this happened. I can't find it. On either set of mailing lists. I searched for gforth, i searched for anton, etc Nothing.
亲历编译器作者认同观点但批评论文语气恶劣,难以赢得支持。
我是编译器作者。我其实并不反对这些观点,也同意面向实际使用的编译器最好能为令人意外的行为提供充分理由。但论文通篇恶劣的语气不会让作者想影响的人买账。
pklausler查看英文原文
I'm a compiler writer. I'm not actually unsympathetic to these points, and agree that compilers intended for practical use had better have strong justification for surprising behavior. But the pervasively nasty tone of the paper is not going to make many friends among the people whose work the authors are trying to influence.
质疑用具体越界代码例子说明编译器优化合理,程序员应先避免未定义行为。
这段代码(d[16] 循环访问 d[++k] 越界)被优化成无限循环,论文说这是不正确的。我站在编译器这边。这段代码本身就是坏的;如果你做了越界访问,无限循环是你最不用担心的问题。
AndyKelley查看英文原文
int d[16]; int SATD (void) { int satd = 0, dd, k; for (dd=d[k=0]; k<16; dd=d[++k]) { satd += (dd < 0 ? -dd : dd); } return satd; } This gets optimized into an infinite loop, and the paper says that this is incorrect. I'm on the side of the compiler. This code is broken, if you do an out-of-bounds access then an infinite loop is the least of your worries.
质疑从经济现实角度反驳:应用代码远多于编译器代码,在编译器内实现优化更划算;问题根源在 C 语言设计。
作者在第 4 节似乎在说,编译器应该停止做某些优化(比如在适当时候把 int 转成 size_t),并期望程序员自己去做这些优化,以减少未定义行为。这个论点的问题在于它不符合经济现实。编译器作者不会反对不必做这些优化!(比如 Chris Lattner 就对我就这么说过。)不幸的是,应用代码远多于编译器代码。所以在编译器里加优化、让海量 C/C++ 程序无需手工优化就能受益,在经济上更合理。这就是为什么 Google 和 Apple 这样的公司雇佣编译器工程师:让它们的大型代码库自动变快。抱怨编译器工程师很时髦,因为他们是容易攻击的目标,也因为人们怀念 Turbo Pascal 时代——那时不做优化,程序很慢。但分析导致 C/C++ 中未定义行为被利用的复杂成因就不那么时髦了。在我看来,如果非要归咎于一个东西,那应该是 C 语言本身,比如它鼓励用 int 做数组下标。附:Fabian Giesen 关于编译器为何利用有符号溢出的解释总是必读。
pcwalton查看英文原文
The author seems to be saying, in section 4, that compilers should just stop doing some optimizations (such as converting int to size_t where appropriate) and should expect programmers to do those optimizations instead, in order to reduce undefined behavior. The problem with this argument is that it doesn't match economic reality. Compiler authors wouldn't disagree that it would be nice to not have to do these optimizations! (Chris Lattner has said as much to me, for example.) Unfortunately, there is a lot more application code out there than there is compiler code. So it makes economic sense to add optimizations to the compiler rather than to individual programs, so that the huge universe of C and C++ programs can benefit without having to be optimized by hand at the source level. This is why companies like Google and Apple employ compiler engineers: so that their large codebases can become faster automatically. It's trendy to complain about compiler engineers because they're an easy target, and because of nostalgia for the days of Turbo Pascal when optimizations weren't done and programs were slow. It's much less trendy to analyze the complex circumstances that has led to UB exploitation in C and C++. In my opinion, if I had to assign blame to one thing, it would go to the C language itself, for e.g. encouraging use of int for array indices. P.S. As always, Fabian Giesen's description of why compilers exploit signed overflow is a must-read: https://gist.github.com/rygorous/e0f055bfb74e3d5f0af20690759de5a7 Note that the conclusion is not as simple as "compilers should stop doing this optimization in C". There in fact isn't a great solution precisely because int is 32 bits for popular ABIs in C; the best options are "hope the programmer used size_t right" or "use another language".
历次讨论
- 2016Hacker News 讨论帖122 分 · 106 评
- 2019Hacker News 讨论帖88 分 · 62 评
同领域还值得读
Google 的软件工程(2017)
Software Engineering at Google (2017)
介绍了 Google 的软件工程实践,包括其单一代码库(monorepo)、几乎全部开发在主干进行而非分支、代码审查、构建系统 Blaze、协议缓冲区等工具与流程,并讨论了频繁重…
编程语言与软件工程2017 · 1,127 分 · 465 评 · 引用 15入门 · 约 45 分钟编辑精选Peter Naur:编程作为理论构建 (1985)
Peter Naur – Programming as Theory Building (1985)
Peter Naur 1985 年的经典论文《Programming as Theory Building》提出:编程的本质不是写代码或文档,而是在程序员头脑中构建对程序及其运行…
编程语言与软件工程2016 · 629 分 · 74 评入门 · 约 45 分钟编辑精选SciPy 1.0:Python 科学计算的基础算法
SciPy 1.0: fundamental algorithms for scientific computing in Python
这篇发表于 Nature Methods 的论文介绍了 SciPy 1.0——Python 科学计算生态的基石库,涵盖其核心算法模块(优化、积分、插值、线性代数等)、软件架构与社…
编程语言与软件工程2020 · 387 分 · 98 评入门 · 约 45 分钟编辑精选Lisp 的历史(1979)
History of Lisp (1979)
这是 Lisp 发明者 John McCarthy 于 1979 年为 HOPL(编程语言史)会议撰写的回顾文章,讲述 Lisp 的起源、设计动机与早期演进,文中也涉及 if 表…
编程语言与软件工程2018 · 352 分 · 44 评入门 · 约 45 分钟编辑精选使用 NumPy 进行数组编程
Array Programming with NumPy
这篇 Nature 文章介绍 NumPy 的数组编程模型及其在科学计算中的核心作用:以 ndarray 为中心,通过向量化操作让 Python 高效处理多维数组。
编程语言与软件工程2020 · 318 分 · 134 评入门 · 约 40 分钟编辑精选