有两点需要先说明: 1、林纳斯( Linus Torvalds )是一位极具天赋、意志坚定的工程师,他对计算领域的贡献无可估量——最广为人知的是 Linux 内核,此外还有 Git; 2、像所有资深开发者一样,他对代码风格有着非常鲜明的个人主张。在维护像 Linux 内核这样由成千上万人协作的超大型项目时,强制推行统一的编码规范至关重要;但在你自己的小项目里,是否遵循他的观点就没那么关键了。那他到底为什么讨厌“数组形参”?
核心原因很简单:C 语言中根本就不存在“数组作为函数参数”这回事!
当你写下这样的函数声明:
voidfoo(int arr[10 ]);编译器并不会真的把 arr 当作一个长度为 10 的数组传进去——它会 悄悄地、静默地 把它转换成一个指针:
voidfoo(int *arr);这种行为源于 C 语言早期的历史设计,如今虽然被保留下来,但本质上是一种“障眼法”。正如林纳斯在 2015 年一封著名的邮件中直言不讳地说:
“C 语言中根本不存在数组参数。可悲的是,出于一些糟糕的历史原因,编译器居然接受了这种写法,并默默地把它变成指针参数。支持这种写法的人,脑子都不太清醒。”问题出在哪?来看一个真实例子
他在那封邮件中批评了一段无线网络驱动代码:
staticboolrate_control_cap_mask(..., u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN]){for (i = 0; i < sizeof(mcs_mask); i++)...}
乍看之下似乎没问题,但这里埋了两个致命错误:
-
mcs_mask被声明为数组,实际却是指针; -
sizeof(mcs_mask)返回的是指针的大小(4 或 8 字节),而不是数组的真实长度!
结果就是:循环只跑了 4 次(32 位系统)或 8 次(64 位系统),而本该跑 10 次(因为 IEEE80211_HT_MCS_MASK_LEN == 10 )。虽然碰巧因为每个元素是 1 字节,且前几个元素可能就满足条件,所以 bug 在测试中没暴露出来——但这仍然是 逻辑错误 + 语义混淆 的典型。
林纳斯( Linus Torvalds )怒斥道:
“这段代码之所以看起来‘合理’,完全是因为第一个错误(用数组形参)掩盖了第二个错误(误用 sizeof)。它本质上是一堆互相喂养的垃圾。”
正确的写法应该是:
参数直接声明为指针:
u8 *mcs_mask循环边界明确使用常量:
for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
或者,如果真想表达“这是一个固定长度的数组”,那就 不要依赖形参语法 ,而是通过注释、命名或配套的宏(如 Linux 内核中的 ARRAY_SIZE() )来传达意图。
为什么这种写法危害更大?
林纳斯特别强调: 这种写法具有欺骗性 。
它看起来像是在“文档化”参数的预期长度(比如
[10]好像在说“我期望传入一个 10 元素的数组”);但实际上,编译器完全忽略这个数字,也不会做任何边界检查;
更糟的是,它会诱导程序员写出
sizeof(arr)这种看似合理实则错误的代码。
“这根本不是文档,这是在撒谎。误导性的‘文档’比没有文档更危险。” —— Linus Torvalds
在他看来,写 int arr[10] 作为参数,等同于向全世界宣告:“我不懂 C 语言”。
那我们该怎么办?
- 如果你在参与 Linux 内核或其他遵循林纳斯规范的项目: 请严格避免数组形参,一律用指针。
- 在你自己的项目中 :虽然技术上可以用,但要清楚它只是“语法糖”,背后仍是裸指针。务必避免在函数内使用
sizeof 获取数组长度。 - 更好的实践: 显式传递数组长度,或使用结构体封装指针+长度,或者借助宏(如
ARRAY_SIZE)提高可读性和安全性。
林纳斯讨厌“数组形参”,不是因为他固执,而是因为:
它 名不副实 (声称是数组,实则是指针);
它 容易引发隐蔽 bug (尤其是配合
sizeof使用时);它 制造虚假的安全感 ,让开发者误以为编译器会帮忙检查数组边界。
正如他所说:“当看到这种明显荒谬的代码时,我会非常愤怒——因为它让我担心那些我没发现的、更隐蔽的问题。”
所以, 与其依赖这种“看起来漂亮但暗藏陷阱”的语法,不如老老实实写指针,清清楚楚传长度——这才是真正的“懂 C” 。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.