林纳斯·托瓦兹与所谓的“垃圾代码”
林纳斯·托瓦兹批评谷歌工程师提交的RISC-V Linux内核代码是“垃圾代码”。争议焦点在于辅助函数make_u32_from_two_u16()与托瓦兹提议的显式代码方案。
林纳斯·托瓦兹批评谷歌工程师提交的RISC-V Linux内核代码是“垃圾代码”。争议焦点在于辅助函数make_u32_from_two_u16()与托瓦兹提议的显式代码方案。让我们探讨正确类型转换、位操作以及创建更安全可复用宏/函数的重要性——这些实践能提升代码清晰度并减少缺陷。
近日,林纳斯·托瓦兹公开斥责谷歌工程师提交的RISC-V内核代码为“垃圾代码”:
https://lkml.org/lkml/2025/8/9/76
首先,我认为林纳斯应当更尊重他人。
此外,让我们聚焦于make_u32_from_two_u16()辅助函数。据我理解,这是C语言预处理器宏(因Linux内核主要用C语言编写)。让我们将该辅助函数与Linus提出的显式代码“(a << 16) + b”进行对比。
首先,该显式代码很可能存在错误,事实上Linus补充道“可能需要添加强制类型转换”。
为何需要强制类型转换?用林纳斯的话说:“[…] 确保’b’的高位不会污染最终结果”。那么按他的思路,显式代码应写成“(a << 16) + (uint16_t)b”吗?
但让我们退一步思考:我们应该自问:’a’和’b’的类型是什么?从辅助函数的名称来看,我认为它们是两个“u16”,即两个uint16_t。
如果让我编写一段C代码,要求将两个uint16_t值'和a''b'作为输入并组合成uint32_t,我会这样写:
((uint32_t)a << 16) | (uint32_t)b
我会使用_位运算_或(|)而非加号(+);我认为这更合适,因为我们此刻正在进行位操作层面的处理。不过这或许只是个人偏好和编码风格的问题。
此外,我会像上面示例那样对'a'和'b'都进行类型转换。
我不确定Linus所说的“b的高位可能污染最终结果”具体指什么。难道’b‘本身就是uint32_t类型?若属此情况,我会使用0xFFFF这样的位掩码配合位与运算(&)清除’b‘的高位。
另外,我还会为’a‘和’b‘取更清晰的名称,比如’high‘和’low‘,明确区分高16位字和低16位字。
因此,正确的显式代码绝非简单如“(a << 16) + b”。你可能需要进行类型转换,且必须正确使用括号确保语法无误。同时还需注意:是否需要用位掩码清除’b’的高位?
如果将两个uint16_t组合成uint32_t的操作出现在多个位置,那么采用Linus邮件中提倡的显式代码,确实会增加引入错误的机会!
因此,更优雅、清晰、安全的方式是提升代码的语义层次,编写辅助函数或宏来安全正确地完成组合操作。
一个C语言宏可能如下所示:
#include
#define MAKE_U32_FROM_TWO_U16(high, low) \
( ((uint32_t)(high) << 16) | (uint32_t)(low) )
是否需要考虑’low’的高位需要清除的情况?此时宏将变为:
2
#define MAKE_U32_FROM_TWO_U16(high, low) \
( ((uint32_t)(high) << 16) | ((uint32_t)(low) & 0xFFFF))
如你所见,类型转换、括号使用以及潜在的位掩码操作确实需要谨慎处理。但一旦代码正确无误,你就能在每次需要时安全便捷地复用它!
因此真正的垃圾代码,其实是反复编写显式易错的代码,比如“(a << 16) + b”!而非像上文那样,将这类代码封装到合理的辅助宏(或函数)中。
在C++中,我们可以定义内联辅助函数替代预处理宏,例如:
#include
inline uint32_t make_u32_from_two_u16(uint16_t high, uint16_t low) {
return (static_cast(high) << 16) |
static_cast(low);
}
我们甚至可以进一步优化这个函数,标记为_noexcept_,因为它保证不会抛出异常。
同时还可以将函数设为_constexpr_,因为当输入参数为常量时,它可以在编译时进行评估。
经过这些额外优化后,我们得到:
inline constexpr uint32_t make_u32_from_two_u16(
uint16_t high,
uint16_t low) noexcept
{
return (static_cast(high) << 16) |
static_cast(low);
}
本文由 TecHug 分享,英文原文及文中图片来自 Linus Torvalds and the Supposedly “Garbage Code”。
共有{51}条精彩评论
> 我觉得林纳斯应该更尊重他人
你们都该练就更厚实的皮肤。若我们真是工程师,就该直面批评。林纳斯的评论针对的是代码本身,从未侮辱开发者。若你将自我价值与编写的代码挂钩,那是你自己的问题。
你们想让他怎么做?用糖衣炮弹吗?“呃亲爱的请重写这个函数,它还不够完善”?
这是PR(合并请求),对代码的诚实公正反馈(及改进建议)才是唯一要务。若代码是垃圾,审阅者就该直言不讳。
这是个高度公开的邮件列表,每当Linus发表此类评论,都会被广泛传播。
去谷歌搜索那位工程师的名字吧。尽管他参与了RISC-V的创建,但几乎所有搜索结果都包含“垃圾”这个词。若我的职业声誉遭遇此等羞辱,我会羞愧难当,精神上彻底崩溃。我没有厚脸皮承受成千上万人的嘲笑。
仅凭这一点,我永远不会考虑参与Linux内核开发,也会劝阻他人参与。
批评他人作品本不必沦为看客运动,许多人始终能做到理性评价。
至于你评论中的“亲爱的”:这世界远不止黑白两色。你该尝试看看。
哇,这可糟了。我没想到会对SEO造成这么大的影响。
没错。现在想象一下,对于那些在其他领域并不出名的工程师来说,影响会有多大。
以下是林纳斯评价提交代码时用的词:疯狂、愚蠢、垃圾、需要重写、难以理解。
你愿意在用这种词反馈的地方工作吗?我肯定不愿。不过也许我就是个玻璃心。
背景是:如此规模的合并请求本应在合并窗口期前提交,而此请求却在窗口期后提交,且修改了其他子树使用的通用头文件。此类情况此前也曾发生。
因此评论不仅针对代码本身,更指向整个处理流程。最终结论是允许修改但不得触及通用头文件,并建议在下个版本周期初期重新提交PR。
这种措辞并非煽动性言论,而是严正态度,且为未来提交留有充分余地。
若在我的职场遇到这种情况会介意吗?大概不会。尤其当我的上司是位经验丰富的知名程序员,且能与我分享行业内幕时。
关键在于,若他能在合适时机收到这个补丁,打赌他会如何评价?大概率会指出代码质量问题,给出相同反馈但措辞会温和许多吧?
我感觉他更在意的是时机问题,虽然对代码本身不满意,但他的反应_正是因为_时机不对。不过邮件的措辞方式让人难以判断。
如果发件人是像林纳斯这样受人尊敬的工程师,那另当别论。但如果是能力平平却自视甚高的人?绝无可能。
关键在于上下文。
所以只要你是受人尊敬的同行,就能肆意辱骂他人而逍遥法外?
这种逻辑只会滋生暴君。
若能让我成为更优秀的工程师且反馈合理,当然可以。但若攻击我的个人信仰或家人,那便是另一回事。
我并非主张所有人都适用此法。若有人无法从中获益,完全可以另寻良师。
你可以给出诚实公正的反馈,无需侮辱他人或其作品。
软件工程是协作过程,而非对抗过程。
> 软件工程是协作过程,而非对抗过程。
协作过程本身就存在对抗性。当他人贡献违背自身目标时妥协,实则背离了目标。有时为达成次要目标而妥协,总比完全无法达成目标要好。但当 stakes 极高(而 Linux 的 stakes 极其巨大)时,妥协目标便不再合适。Linux 和 Linus 处于无需妥协目标的地位。
用不同措辞拒绝代码究竟算哪门子“投降”?
在软件工程领域待得够久,职业生涯里总会多次遭遇这类社交失调的小暴君。不过看到这么多暴君在本帖里自曝其短,倒也挺有意思。
确实,但不确定
> 这种行为会让世界变得更糟
是否真有必要用这种方式表达观点。
这难道不是双向的吗?如果我们是“真正的工程师”,就不该用夸张手法表达“这既没按时完成,质量也不达标,我厌倦了反复强调”这种简单道理。
实际上,沟通方式至关重要——即便在工程领域亦然。这并非要求时刻保持绝对客观(现实交流本就如此),而是需要花时间理解对方如何接收我们的言辞。
试想:若我想让你去商店,却始终用某个无意义的词代替“商店”,我们都会认为这是糟糕的沟通。因为我知道你听不懂那个词,自然无法理解我的意图。
语气亦是如此。语气是沟通的一部分,因此当我使用过于激进或过于客气谨慎的语调时,你就无法理解我真正想表达的意思。找到恰当的语气对良好沟通至关重要。具体语气取决于对话对象——与朋友交谈时我会用一种语气,与陌生人则另当别论;对英国人表达时采用一种方式,与德国人交流时则另有一套。
顺带一提,我注意到Linux邮件列表的交流风格普遍偏好针锋相对,若这是林纳斯营造的文化氛围,他选择这种沟通方式也无可厚非。当然潜在风险在于:若始终维持这种交流模式,当不熟悉该文化的新人加入时,沟通障碍可能令其望而却步。
他描述的是代码,而非编码者。
这并非对编码者的攻击,仅是对其产出的评价。
若我们总将对作品的批评视为对自身的攻击,那么整个社会都将陷入困境。
咦,我对最后一段的看法几乎完全相反。认识到我是作品的创作者,因此必须对作品质量(以及这次的时效性)负责,这才是自我反思的核心。若缺乏这种认知,我如何提升能力?当对作品的批评与自我批判完全割裂时,我就无法成长——因为我从未真正被批评过。
我觉得这里存在一个中间地带:我理解工作中的失败未必定义我的价值,但我仍需为之负责。
其实你完全可以不带贬损地表达反馈。无需刻意粉饰。让我们重新解读托瓦兹那段话,去除那些抨击和辱骂:
> 不行。这段代码质量糟糕透顶,提交时间又太晚。我要求提前提交拉取请求是因为正在出差,若你无法遵守规则,至少确保提交的代码质量合格。
稍作调整:
> 这段代码将大量非RISC-V特有的低质量代码添加到通用头文件中。
垃圾代码
> 合并窗口期临近时收到如此糟糕的代码,我深感愤怒。
其实他并非真正愤怒于代码本身,而是对提交时机不满。要我说,若这段代码在合并窗口期前很久就提交,他态度怕是温和得多。
例如这个 make_u32_from_two_u16() 辅助函数。它让代码变得难以理解,甚至比根本不使用它还要糟糕。
“那玩意儿让世界变得更糟”——但事实真是如此吗?许多事物都在让世界变得更糟:疾病、犯罪、狗狗币…但辅助函数真能主动削弱人类生存能力吗?
> 若将代码写成“(a << 16) + b”,你就能明确理解其作用及高位字符的处理方式。或许你需要添加强制类型转换来确保'b'的高位不会污染最终结果,所以代码可能不够优雅,但至少不会出错或令人费解。
看,这难道很难吗?我根本没改动任何内容。
> 反观 make_u32_from_two_u16(a,b) 的写法,你根本无法确定字节序。换言之,你不仅让情况变得更糟,还把这个辅助函数塞进了通用非RISC-V文件。若他人使用此函数,必将拖累其他代码质量。
我几乎没改动什么,但没粉饰太平。
> 所以不行。请别把这类函数写进代码。它们不该出现在通用头文件里,更别说在合并窗口后期才提交。
注意我保留了“该死”这个词。
> 警告你:不准再提交迟到的拉取请求,也不准在RISC-V代码库外添加无关代码。
这很合理。托瓦兹生气是有道理的。
> 现在,我_希望_RISC-V部分没有类似代码,但这取决于你的选择。不过通用头文件里的内容不会被这类东西污染。在合并窗口关闭前一天提交大型拉取请求,指望我忙得顾不上处理——这可不是什么好策略。
微调而已。
> 因此你可以在6.18版本重试——在合并窗口期伊始提交,且无需夹带垃圾代码。
毫无改动,甚至还借机用了“垃圾”这个词。
或许我该换种你可能欣赏的表达方式:托瓦兹在沟通中是个混蛋,也是个心智不成熟的人。他沟通能力欠缺,让付出大量时间精力改善现状的人倍感委屈;而当激怒他时,这个情绪失控的卑鄙小人便会暴露本性。
> 或许我该换种你可能欣赏的表达方式:托瓦兹在沟通中是个混蛋,也是个发育不良的人。他无法与他人沟通,导致对方明明付出大量时间精力改善状况却仍感到沮丧;而当激怒他时,这个情绪失控的卑鄙小人便会显露本性。
你看,你在谈论这个人本身,而林纳斯讨论的是代码及其迟交行为。林纳斯的观点要温和得多
我理解你的观点,但代码并非与作者完全割裂。当然,你必须能接受批评且不要过度在意,但我认为不能用各种过于苛刻且毫无建设性的言辞指责代码,然后声称这仅关乎代码本身,与作者毫无关联,因此无伤大雅。毕竟,那些“晦涩难懂”的“垃圾代码”,不正是出自某人之手吗?
作者确实有道理;整个BcacheFS风波部分源于批评其他文件系统设计的评论(当然,压垮骆驼的最后一根稻草是那些暗示开发者需要“检查头脑”的言论,以及在变更冻结期强行添加功能等失当行为)。
我印象中核心问题在于反复无视开发流程,将实验性bcachefs模块的快速推进置于内核稳定性之上
总的来说,四处审查他人讨论并非社会中值得推崇的角色
更具体地说,保持礼貌固然可贵——而林纳斯通常如此。
对代码持有强烈观点本就是他的职责所在。要求他每次都措辞完美且永不显露挫败感——尤其当主要通过公开、基于文本且永久可见的沟通方式工作时——这根本是不可能的标准。
四处评头论足地审视他人讨论,在社会中并非真正有价值的角色。
你描述的本质上是养育子女的行为,而这在社会中具有极其重要的价值。
更广泛地说,最近有人对我引用那句经典箴言:“伟人讨论思想,平庸者讨论事件,愚者讨论他人”,我不得不予以反驳。讨论他人行为本就是人类协商文化价值观、道德规范与礼仪的天然方式,这绝非可轻视之事。
你怎么能把审查他人讨论等同于养育子女?
你是不是用错了词?
养育子女是父母对亲生子女的行为,不是对网络陌生人的…
我从未见过自己或同事称其他开发者的代码为“垃圾”。混蛋行为永远不可接受。无论你是林纳斯、乔布斯,还是那些偶然有点才华的无穷无尽的霸凌者。
这太不可思议了,在我看来这可是家常便饭。我写过被当面指责的垃圾代码,有时对方措辞相当不礼貌;我也指责过别人的垃圾代码,有时同样不留情面。
当然保持礼貌更好,但我不会因为有人偶尔失态就称其为混蛋或霸凌者。
恕难苟同。在所有可能的批评中,“垃圾”一词已算相当温和
哈哈,林纳斯·托瓦兹、史蒂夫·乔布斯之流…不过是些“有点才华”的霸凌者罢了
这…这说法连当玩笑都难以成立…
> 更具体地说,保持礼貌是件好事,而林纳斯通常都做得到。
哈?呃…啥?
我没见每天有成千上万条评论在此谴责他,可这可是他几十年的工作方式。每当他说出刻薄话,人们就跳出来指责“看吧这就是他的本性”。说实话这倒成了我们这个时代的症结。
去看看LKML邮件列表就知道了。他确实通常如此。
托瓦兹的暴言总能引发如此关注,这让我感到怪异。就像人们看选秀节目时,听主持人贬低歌手反而觉得乐在其中。
我认为是因为多数软件开发者都曾与混蛋共事过。评论某个出名的混蛋,是宣泄情绪的自然途径。
构建内核很难,对不参与的事发表意见很容易
官方默认检查器的最新Rust稳定版提示:
警告:手动实现`.is_multiple_of()`
| if number % i == 0 {
| ^^^^^^^^^^^^^^^ 建议替换为:`number.is_multiple_of(i)`
```
>>首先,这段显式代码很可能有误,事实上Linus补充道“可能需要添加强制类型转换”。
当你编写显式代码时,你清楚a和b在上下文中的类型。
你不会编写泛型代码,而是为该上下文编写显式的特定代码。某些上下文需要强制类型转换,某些则不需要(因此使用“可能”一词)。
文章其余部分读起来像是一篇讽刺作品。作者本可采用清晰明确的一行代码,却最终写出多行函数,却仍未能解决林纳斯指出的核心问题(即阅读代码时遇到该函数,你无法分辨哪个参数是高位哪个是低位)。
> 阅读代码遇到该函数时,你无法分辨哪个参数是高位哪个是低位
参数定义里写得清清楚楚。你的IDE难道不会提示正确顺序?否则你遇到每个函数都要吐槽?
这根本不是函数,是宏。只是个没有定义参数类型的文本替换规则。
阅读代码差异、搜索结果或PR请求时,并非总能通过IDE查看函数定义。即便能查看,仍需耗费时间点击跳转并阅读定义。参数名称虽有帮助,但并非文档说明,理解仍需时间。
替代方案是使用语言内置的通用运算符。
>>否则你得在遇到每个函数时都添加类似注释。
这是一种权衡。要打包的逻辑越多,其价值就越大。这里我们有一行代码包含两个内置运算符。
原始消息(因lkml链接无法加载):https://lore.kernel.org/lkml/CAHk-=wjLCqUUWd8DzG+xsOn-yVL0Q=…
你不需要在上面添加noexcept,编译器会自动识别,避免潜在的noexcept开销…除此之外——我同意。
我认为这个反驳偏离了重点,前两段已阐明核心问题:
不对。这是垃圾代码,而且加入得太晚了。…这给通用头文件添加了各种与RISC-V无关的垃圾内容。
前半段说得有道理,但最后那段C++代码简直是垃圾。向C语言致敬。
你完全忽略了Linus评论的前半部分,还写了篇“垃圾文章”来抨击它。
حقق تطبيق 888starz انتشارًا كبيرًا بين أصحاب الهواتف الذكية في مصر.
888starz تحميل [url=https://www.theracingbicycle.com/]https://theracingbicycle.com/[/url]
عند تنزيل apk يقوم المستخدم بالنقر عليه لتبدأ عملية التثبيت بشكل مباشر.
يُنصح بتحديث ملف apk فور صدور نسخة جديدة للاستفادة من آخر التحسينات.
يفضل الحصول على apk تطبيق 888starz من المصدر الموثوق لضمان سلامة الجهاز.
يقدم إصدار iOS نفس أداء نسخة أندرويد مع واجهة محسّنة لأجهزة آبل.
يوحّد 888starz تجربة الكازينو والمراهنات الرياضية أمام المستخدم في القاهرة.
تشمل غرف الكازينو الحي 250 طاولة وأكثر للروليت والبكارات والبلاك جاك.
تتغير الاحتمالات في الوقت الفعلي مع خيار المراهنة أثناء اللعب.
يمنح الكازينو أول إيداع بونصًا يصل إلى 1500 يورو و150 دورة مجانية.
888starz [url=https://888starzs13.com/]888starz[/url]
تشمل وسائل الدفع الفيات والعملات المشفرة بحد إيداع يبدأ من 2 يورو.
888stars [url=https://888starzs17.com/]888stars[/url]
تمثل منصة 888starz للاعبي القاهرة وجهة رسمية تجمع الكازينو والرهان الرياضي معًا.
يتوفر في الكازينو الحي أكثر من 250 طاولة بموزعين حقيقيين تعمل بلا توقف.
يشمل الموقع أكثر من 35 فئة رياضية تتابع كبرى الأحداث في العالم.
تتوالى المكافآت الدورية بين الاسترداد النقدي والترقيات الموسمية.
يدعم الموقع البطاقات والمحافظ إضافة إلى أكثر من 50 عملة رقمية بينها BTC و USDT و ETH.
The official website ensures a safe, licensed environment that protects player data and funds.
Trending slot machines and new releases are highlighted prominently on the official site.
The sportsbook on the official 888starz site covers more than 50 sports from around the world.
888starz highlights the latest bonuses and promotions available to players in Uzbekistan.
888starz lets users create a new account in several ways in only a few minutes.
888starz apk [url=http://fysiozuid.nl/]888starz apk[/url]
Everything from slots to live tables is available on the official True Fortune site.
The lobby showcases jackpot slots and the latest releases right at the top.
The VIP scheme gives loyal users cashback boosts, gifts and a personal manager.
Withdrawals are handled quickly, with e-wallet payouts often completed the same day.
promo code true fortune [url=https://true-fortune-casino25.com/promocode]promo code true fortune[/url]
The site offers deposit limits, reality checks and self-exclusion for safer play.
A detailed FAQ and clear terms make it easy for players in the United Kingdom to find answers fast.
你也许感兴趣的:
- 林纳斯·托瓦兹:Linux内核版权许可仅涵盖软件,不延伸至硬件
- Linus Torvalds的业余项目:随机吉他踏板设计
- BitKeeper、Linux 和许可纠纷:Linus 如何在 14 天内写出 Git
- 【译文】 Linus Torvalds 在 Linux Kconfig 中故意将缩进的使用复杂化
- Linus Torvalds:Linux 内核、社区多元化和开发者的未来
- Linus Torvalds:我不再了解编程,不再是一名程序员了
- 被 Linus Torvalds 批评过的十一种技术
- Linux之父Linus Torvalds谈Linux行为准则
- Linux创始人公开道歉 他真的会改变吗?
- Linus Torvalds:我不看好量子计算

发表回复