C程序员再犯可读性罪行
摘要
2025年国际混淆C代码大赛获奖者揭晓,共有23个参赛作品,其中包括Adrian Cable的Subleq计算机模拟器,该模拟器通过单指令集架构实现软件保存。
暂无内容
查看缓存全文
缓存时间: 2026/07/06 14:04
# C程序员再次挑战可读性底线
来源:https://www.theregister.com/offbeat/2026/07/05/c-programmers-commit-fresh-crimes-against-readability/5265981
第二十九届国际C语言混乱代码大赛(https://www.ioccc.org/2025/index.html)——简称IOCCC——携2025年竞赛结果回归。今年,其中一位参赛者祭出了一项独门绝技:一个实际有效的用例。当我们在去年报道(https://www.theregister.com/software/2025/08/09/the-international-obfuscated-c-code-contest-is-back-for-2024/1065530)这一赛事时,它刚刚从四年的休眠期恢复,因此我们很高兴看到它这么快又回来了。在我们撰稿时,评审已于三周前结束,但尽管YouTube上有一段录像(https://www.youtube.com/watch?v=MoWCwZx1Swc),时长却接近三个小时。将其剪辑成每个获胜者单独的片段花了一些时间,这也是我们此时才报道的原因。对于其中许多程序,你必须亲眼看到它们的效果才能相信,虽然视频片段通常不是我们偏好的格式,但此时却非常适合展示。
今年共有不少于23个获奖作品(https://www.ioccc.org/2025/index.html#inventory),其中包括一个帽子戏法中的帽子戏法:三名参赛者——**Yusuke Endoh**(https://github.com/mame/)、**Nick Craig-Wood**(https://www.craig-wood.com/nick/)和**Don Yang**(https://uguu.org/)——各自赢得了三个奖项。我们只能挑选个人认为最精彩的几个进行介绍,但我们强烈建议你阅读所有获奖作品——它们绝对值得你花时间。
IOCCC的一个特点是评审**Landon Curt Noll**(http://www.isthe.com/chongo/index.html)和**Leonid A. Broukhis**(https://www.mailcom.com/main.shtml)每次都会为每个获奖作品发明新的分类。我们沿用他们的标题,因此如果副标题一开始看起来有些费解,阅读相关的IOCCC页面或许能解释一切……但别抱太大希望。
### IOCCC29 – 2025/cable – 最佳虚拟模拟器
我们不敢声称研究过每一届IOCCC的所有结果。1984年第一届举办时,本秃鹫还在学校学BASIC呢。不过今年,**Adrian Cable**(https://www.ioccc.org/2025/cable/index.html)的*Subleq计算机*(https://www.ioccc.org/2025/cable/index.html)最吸引我们的注意。原因是我们之前已经研究过它及其功能——或者至少是一个密切相关的项目。对于IOCCC来说不寻常的是,它在软件保存方面有一个实际应用案例。
**永恒软件计划**(https://www.eternal-software.org/)(ESI)的理念是通过实现一种专门设计为易于仿真的计算机架构,帮助在原始硬件平台不复存在后保存软件。GitHub上有一个示例实现(https://github.com/adriancable/eternal)。CPU架构并不新鲜;它是一种名为**Subleq**的“单指令集计算机”(https://esolangs.org/wiki/OISC)。OISC是RISC的逻辑外推:你无法将指令集减少到比一条指令更少。在这个例子中,那条指令是Subleq(减法并在小于或等于零时跳转)。这里有一份2020年的解释(https://techtinkering.com/articles/subleq-a-one-instruction-set-computer/),而它在当时也并非新事物——这里还有2011年的FPGA硬件(https://arxiv.org/pdf/1106.2593)\[PDF\]。
ESI已用软件实现了Subleq,利用LLVM构建了一个针对它的C编译器,并将Linux移植到其上,还附带了C和C++运行时库。在该Linux上运行你的模拟器,你就可以从这个微小的基础自举出任何硬件架构的可运行版本。而“微小”一词一点也不夸张。这是该架构的IOCCC获奖实现(https://github.com/ioccc-src/winner/blob/master/2025/cable/prog.c):
```c
#include <SDL2/SDL.h>
#define o s[1&s[t=e++]?s[t]/4:t]/4,t b,y,t,e,s[3<<27],V[32],*w,**g;main(_){for(g =SDL_GetWindowSurface(w=SDL_CreateWindow(0, 800,512,!read(b,s,'frog')));_=o=y=o=o;~_?~y ?e=1>(s[y]-=_[s])?t:*s&&++b>8e5?s[memcpy(3[ g],6[s]+s,25<<16),b=SDL_UpdateWindowSurface (w)]=4*e,*s/4:e:e:SDL_PollEvent(V)?y[s]=6[V ]*(1537-2**V):0)_^64||timespec_get(s+_,1);}
```
这就是全部代码,只有366字节。是的,它依赖于SDL库来显示图形,但即便如此,我们希望你会同意这相当了不起。演示视频展示了它以相当可观的速度生成全彩Mandelbrot集,然后玩一局乒乓游戏,之后再演示Subleq运行Linux和一些应用程序。当你观看时,请记住,你可以手写这份源代码在一张明信片上,并且还有足够空间写地址和贴邮票。它只有九行。代码的一个稍微可读的版本(https://github.com/adriancable/eternal/blob/main/vm/vm.c)仍然只有91行。
### Nick Craig-Wood的帽子戏法
与最佳虚拟模拟器相呼应,还有一个获胜的**最佳真实模拟器**(https://www.ioccc.org/2025/ncw1/index.html)。Nick Craig-Wood提供了一个原版任天堂Game Boy的工作模拟器,仅用66行C代码写成,并且为了参赛,他将其**格式化得像游戏机本身**(https://github.com/ioccc-src/winner/blob/master/2025/ncw1/prog.c)。他的另一个获奖作品是**最佳分数级模拟器**(https://www.ioccc.org/2025/ncw2/index.html):一个难以置信的小巧组合,将Commodore 64模拟器(此处说明)模拟在John Conway的**FRACTRAN**(https://esolangs.org/wiki/Fractran)语言中。他还凭借**最佳Unicode使用**(https://www.ioccc.org/2025/ncw3/index.html)获奖,该作品实现了一个Forth版本,并且在C代码中包含一个Forth程序,用于生成旋转的Mandelbrot缩放效果。
### 2025/endoh1 – 最令人炫目
Yusuke Endoh三个获奖作品中的第一个是一个辉光管模拟器。当*The Reg*的FOSS编辑还年轻时,这就是电子计算器(以及一些汽油泵)显示数字的方式。**辉光管**(https://pentalabs.com/blogs/tube-talk/what-is-a-nixie-tube)是一种微小的电子管,内部有数字形状的灯丝堆叠在一起,通过让特定灯丝发光来显示所需数字。今天你仍然可以买到新的辉光管——一家由**Dalibor Farny**(https://www.daliborfarny.com/)经营的小型捷克公司手工制作它们。
与许多IOCCC参赛作品一样,Endoh的源代码被**格式化得像它模拟的东西**(https://github.com/ioccc-src/winner/blob/master/2025/endoh1/prog.c)。但对于这个作品,这不仅仅是一个有趣的点缀:程序用颜色突出显示自己源代码中的数字,以模拟辉光管的输出。源代码本身也就是输出机制。
我们也被Endoh的第二个作品所吸引,它被评为**最可能令人震惊**(https://www.ioccc.org/2025/endoh2/index.html),该作品在极小的空间中生成**利希滕贝格图形**(https://en.wikipedia.org/wiki/Lichtenberg_figure)。大约在IOCCC刚开始的时候,本秃鹫曾试图自己实现这个,但从未成功过。Endoh的第三个获奖作品,**最具韧性**(https://www.ioccc.org/2025/endoh3/index.html),反复修补自己的代码,然后重新编译自身,从而能够输出……它用来修补代码的diff工具的源代码。至少对本秃鹫来说,这令人费解——它代表了这位日本程序员第23次获胜,这是一个了不起且破纪录的成绩。
在经历了第一和第二作品的震惊与炫目之后,评审们赞扬了**Tomoya Ishida**的**最令人舒缓**(https://www.ioccc.org/2025/tompng/index.html)获奖作品,它仅用**36行代码**(https://github.com/ioccc-src/winner/blob/master/2025/tompng/prog.c)——其中包含"RELAX"的信息——生成了一个包含五分钟氛围音乐的WAV文件,并配有合成海滩声。
### 2025/uellenberg – 乒乓大奖
我们原本以为Endoh的自重新格式化的C代码从其自身源代码输出辉光管效果已经很惊艳了,但随后我们看到了**Jonah Uellenberg**(https://uellenberg.org/)的作品。他的乒乓游戏是一个自产生程序(quine):一个在执行时生成自身源代码作为输出的程序。正如原始Wiki网站**C2的说明**(https://wiki.c2.com/?QuineProgram),这比听起来要难得多。Uellenberg的程序比我们想象的更进一步。
与许多其他IOCCC作品一样,它在自己的**源代码清单**(https://github.com/ioccc-src/winner/blob/master/2025/uellenberg/prog.c)中包含了一条信息。如果你眯着眼看,可以在空白处看到一个乒乓屏幕——两个球拍和一个球。编译并运行它,敲击按键可以移动其中一个球拍……然后它重新格式化自己的源代码并输出一个新的、略有不同的版本,显示更新后的游戏画面。你通过反复编译上一次运行的输出来玩游戏。每次运行都会输出下一局的源代码。游戏的一帧帧画面就是它自己不断变化的源代码。
对于更传统的游戏乐趣,三人合作的作品**最可能传送**(https://www.ioccc.org/2025/jhshrvdp/index.html)相对直接:一个roguelike游戏,仅用**54行可爱代码**(https://github.com/ioccc-src/winner/blob/master/2025/jhshrvdp/prog.c)。对于《神秘博士》的粉丝来说,由一位只知道网名为"jingp49"的台湾程序员创作的**谁赢了奖**(https://www.ioccc.org/2025/jingp49/index.html)作品**看起来像塔迪斯**(https://github.com/ioccc-src/winner/blob/master/2025/jingp49/prog.c),并且输出——我们完全不知道如何做到的——一个ASCII动画版的电视剧片头序列。
我们这里只重点介绍了几个获奖作品。它们都因各种原因而名副其实地令人惊叹。例如,**Gil Dogon**的**始终恒定奖**(https://www.ioccc.org/2025/dogon/index.html)作品输出了欧拉常数的许多位数字,但代码中只有一个变量——自然命名为e。附加价值是,评审和参赛者都用诗歌解释了程序。
感谢**Landon Curt Noll**和*Reg*读者**Anthony C Howe**让我们了解这场竞赛。*The Register*注意到Howe确实有一定利益关系:他赢得了**最可能入侵**(https://www.ioccc.org/2025/howe/index.html)奖,作品是一个真正小巧但可玩的游戏,它让我们想起了某种1980年代的PC游戏——设计成看起来无害,以便你在工作时玩。
### 附注
不要将混乱C代码大赛与**暗箱C代码大赛**(https://underhanded-c.org/)混淆,后者将这种扭曲的天才应用于阴险的目的,而非有趣的花招。®
相似文章
2025年International Obfuscated C Code Contest(IOCCC第29届)获奖者
第29届International Obfuscated C Code Contest(IOCCC 2025)的获奖者已公布,在2020-2024年休整后,提交质量和数量接近历史最高水平。
The Underhanded C Contest
本文宣布了2015年Underhanded C Contest的结果,这是一个专注于编写欺骗性恶意C代码的编程竞赛,今年的挑战涉及核验证,并强调了NaN中毒攻击。
用C语言搞怪,第&((int*)-8)[3]部分
一篇幽默的教育性文章,涵盖C语言基础知识,如前向声明、运算符优先级、无条件跳转和基本算术运算,并附带有意搞怪的代码示例。
面向程序员的逻辑学 v0.15,现场编程
Hillel Wayne 宣布其著作《Logic for Programmers》的 0.15 候选版本,并重点介绍了一场以 Strudel 和 CLAVIER-36 为特色的现场编程聚会,用于音乐编程。
当编译器让你惊喜
Matt Godbolt 探讨了编译器优化如何将 O(n) 求和循环转换为 O(1) 的闭式解,突出了 Clang 和 GCC 如何采用循环展开和数学简化等复杂技术来大幅提升代码性能。