编程与软件工程damienkatz.net
C 语言不可思议的有效性
The Unreasonable Effectiveness of C
2013 — 2014,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
Damien Katz 这篇 2013 年的文章为 C 语言辩护:正因为它简单、编译快、运行时几乎为零、ABI 通用、能直接调用任何库,C 反而是“不合理地高效”的高级语言——写起来接近机器模型,却足以搭出大型系统。作者承认 C 有缺点,但认为它的极简带来的生产力和可组合性被严重低估。
为什么经久不衰:它把一个长期争论摆上台面:语言的“简陋”究竟是缺陷还是最大优势,读它能帮你想清楚自己到底需要抽象还是需要控制力。
HN 评论精选
逐条反驳原文:性能、标准库、工具链、构建速度和 ABI 通用性都被夸大了。
得了吧,又是些无知之谈。更现实的看法是:C 的虚拟机模型和现代架构匹配得并不好,它对机器细节的直白反而常常让 Fortran 编译器生成更快的代码;C 的标准库是个笑话,字符串处理上的缺陷要为过去四十年里惊人比例的安全漏洞负责;它的工具链(尤其调试器)远不如同时代的 Smalltalk、Lisp;说 C 的编译-调试-运行循环快,只是因为 C++ 在这方面太糟,看看 Turbo Pascal;说 C 通过标准 ABI 可以被任何地方调用,等于把全世界都当成 Unix。
madhadron查看英文原文
Oh for heavens' sakes. Yet more ignorance. A more realistic view of C: - C is straightforward to compile into fast machine code...on a PDP-11. Its virtual machine does not match modern architectures very well, and its explicitness about details of its machine mean FORTRAN compilers typically produce faster code. The C virtual machine does not provide an accurate model of why your code is fast on a modern machine. The social necessity of implementing a decent C compiler may have stifled our architecture development (go look at the Burroughs systems, or the Connection Machine, and tell me how well C's virtual machine maps to them). - C's standard library is a joke. Its shortcomings, particularly around string handling, have been responsible for an appalling fraction of the security holes of the past forty years. - C's tooling is hardly something to brag about, especially compared to its contemporaries like Smalltalk and Lisp. Most of the debuggers people use with C are command line monstrosities. Compare them to the standard debuggers of, say, Squeak or Allegro Common Lisp. - Claiming a fast build/debug/run cycle for C is sad. It seems fast because of the failure in this area of C++. Go look at Turbo Pascal if you want to know how to make the build/debug/run cycle fast. - Claiming that C is callable from anywhere via its standard ABI equates all the world with Unix. Sadly, that's almost true today, though, but maybe it's because of the ubiquity of C rather than the other way around. So, before writing about the glories of C, please go familiarize yourself with modern FORTRAN, ALGOL 60 and 68, Turbo Pascal's compiler and environment, a good Smalltalk like Squeak or Pharo, and the state of modern pipelines processor architectures.
工程化视角:构建、IDE、依赖管理和协作才是 C 项目的真正痛点。
它也有几个缺点:构建系统是散的——make、qmake、cmake、autotools、scons,整个生态都在解决这个问题;IDE 大多把 C 当二等公民,VS 官方放弃 C,Xcode 勉强支持,重构和大代码库支持几乎没有;因为构建系统混乱,依赖管理是地狱,一个库用 scons、一个用 autoconf,再加上 rpath 这类晦涩机制;协作门槛高,提交一个能用又不引入漏洞和内存泄漏的补丁很难。
shadowmint查看英文原文
It also has a few downsides: - The build system is broken. vs. make. qmake. cmake. autotools. scons. 'modern' makefiles (>_> what does that even mean? Yes, I'm looking at you Google) There's a whole ecosystem of tools out there to solve this. - There are a few rubbish IDEs, most of which support c as a second class candidate. VS has officially abandoned C; xcode grudgingly supports it. The CDT is mediocre. There's little or no support for refactoring or doing other things on large code bases, and the majority of the time the work has to be done manually. - Because the build system is broken, dependency management is hell Got one library that uses scons, another using autoconf, and what to build a local dev instance of a library without installing it into the system path? Goooood luck. This is made even worse by arcane things like rpath, which mean that dynamic libraries only work when they are in specific paths relative to the application binary (I'm looking at you OSX). - Its a terrible collaboration platform. Why? Because the barrier to entry is high. To submit a patch that works and doesn't break other things, doesn't introduce serious security holes or memory leaks is hard. Astonishingly, some successful projects like SDL are actually written in C, but most C projects are not collaboration friendly. - There are no frameworks for doing common high productivity tasks in C, only low level system operations, or vastly complicated frameworks with terrible apis (>_> GTK). I'll just whip up a C REST service that talks to mysql and point nginx at it. Um... yeah. I'm sure there's an easy way to do that. ...perhaps...? How about a quick UI application? We'll just use GTK, that's portable and easy. ...Or, not very easy, and vastly complicated to setup and build. These issues aren't unique to C, but they're certainly issues. I'm not really sure I'd happily wonder around telling people how amazing C is at everything. It's a tool for some jobs; definitely not all.
一段语言演化循环的自述:C→C++→Java→又想回到 C,最终对哪种语言都不满意。
我从 C 起步,用宏和库重新发明了对象,于是转向 C++;用了多年后被语言的复杂度和特性间的微妙交互烧伤,又厌倦了内存管理,于是投奔 Java。当时还疑惑“每个对象都在堆上?真的没法把一个对象嵌入另一个里面?”,但其他方面太舒服就不在乎了。现在我要写几个想吃掉几 GB 内存、装着几百万个大小不一的对象的系统,每对象开销要命、GC 调优是噩梦,我在做子分配、写微基准比较普通对象和序列化到字节数组的对象——而 C++ 已变成一团更大的乱麻,我又开始怀念 C。
geophile查看英文原文
C/C++/Java. A programmer's version of Rock/Paper/Scissors. Ignoring pre-history (BASIC, FORTRAN, PDP-11 assembler, Z80 assembler, Pascal), I started out in C, many years ago. I found myself using macros and libraries to provide useful combinations of state and functions. I was reinventing objects and found C++. I was a very happy user of C++ for many years, starting very early on (cfront days). But I was burned by the complexity of the language, and the extremely subtle interaction of features. And I was tired of memory management. I was longing for Java, and then it appeared. And I was happy. As I was learning the language, I was sure I missed something. Every object is in the heap? Really? There is really no way to have one object physically embedded within another? But everything else was so nice, I didn't care. And now I'm writing a couple of system that would like to use many gigabytes of memory, containing millions of objects, some small, some large. The per-object overhead is killing me. GC tuning is a nightmare. I'm implementing suballocation schemes. I'm writing microbenchmarks to compare working with ordinary objects with objects serialized to byte arrays. And since C++ has become a hideous mess, far more complicated than the early version that burned me, I long for C again. So I don't like any language right now.
主张做 C 的内存安全方言(如 Cyclone)并标准化字符串库,而不是另起炉灶。
有时我觉得,解决安全问题的最佳方案不是造 Go、Nim、Rust、D 这样的新系统语言,而是在 ANSI C 上做一个内存安全的方言,顺便标准化一套更好的字符串库。AT&T 2001 年就启动过这样的项目,叫 Cyclone,2006 年发布 1.0,后来被放弃了,实在可惜。C 是原始的语言,但最大的弱点也是最大的优势:它极简、心智负担主要来自手动内存管理和标准库陷阱,却也因此在某些时候意外地好用。更重要的是,大量 API(比如 POSIX)都是围绕 C 定型的。
vezzy-fnord查看英文原文
Honestly, sometimes I think that the best solution for fixing the security quagmire we're in would have been not by creating a new system programming language like Go, Nim, Rust, D or even reviving one of the Wirthian languages (though having them on the table is very much a good thing), but by creating a memory safe dialect of ANSI C, and perhaps standardize on a better string handling library. In fact, such an effort was started at AT&T back in 2001. The language was named Cyclone [1]. It met its 1.0 release in 2006. It has since been abandoned. Which is a damn shame, because it looked like it had real potential. Is C a primitive language? Yes. In fact, it's almost stupidly simple compared to most modern languages. But its greatest weakness also proves to be its greatest strength. The main cognitive overhead from using C is in its manual memory management model and certain gotchas in standard libraries. It being bare bones as it is (but not too much) also makes it surprisingly pleasant at times. I get the feeling that plenty of modern languages try too hard to be novel and, for all the freedom you get from not having to worry about anything below program logic itself, you still end up expending a lot of effort into complicated high-level patterns that are frequently interspersed with arcane PL theory. But that's not even the main reason why something like Cyclone is much needed. No. It's that we've pretty much perfected a ton of our APIs, like POSIX, to work with C. It simply feels most natural to work with POSIX in plain C. FFIs and bindings vary, some of them like Nim's actually feel quite clumsy (otherwise Nim makes it absolutely trivial to create FFIs, which is great). Finally, refactoring 30 years worth of code into Cyclone sounds far more realistic than rewriting the world in Rust. [1] https://en.wikipedia.org/wiki/Cyclone_%28programming_language%29
历次讨论
同类还值得读
开源应用架构
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编辑精选