核心内容摘要
Airborne漏洞分析与利用:CVE-2025-24252实战指南
如果你问大多数长期写 C 的人尤其是用现代 C 的开发者“C 最不应该存在的特性是什么”答案其实高度分散但经常被反复点名的几个“罪魁祸首”集中在下面这几类按被吐槽频率从高到低排序2024–2025 社区共识视角Top 候选名单社区最常提的“应该删掉/重做”的特性C 风格数组 指针衰退array-to-pointer decay 裸指针泛滥几乎是压倒性票数第一的“原罪”。
为什么最该死C 从 C 继承了“数组名退化为指针”的规则导致int a[10]; func(a);瞬间丢失大小信息埋下无数越界、内存安全隐患。
现代 C 明明有std::span、std::array、std::vector、std::string_view但语言层面仍然允许/鼓励裸指针 衰退导致新手/老代码继续写不安全代码。
很多人直言“如果 C 一开始就把数组当成第一类对象带边界检查安全性起码提升一个数量级。
”隐式转换地狱尤其是单参数构造函数 转换运算符bool operator bool()、operator int()、MyString(const char*)这些东西导致的意外转换、歧义、重载解析爆炸。
C11 加了explicit但默认还是允许历史包袱太大。
Herb Sutter 等人在安全 profile 里都想把大部分隐式转换干掉。
多重继承 虚继承virtual inheritance菱形继承问题、虚基类指针偏移、内存布局不可预测、调试地狱。
现代 C 几乎没人敢用多继承实现都用接口 组合但语言还保留着完整的机制增加理解成本和编译器复杂度。
C 风格字符串char strcpy / strlen / sprintf 家族*缓冲区溢出之源安全漏洞温床。
C 提供了std::string几十年了但标准库和 C API 还在到处用const char*强制大家写strlen、strcpy_s等防御代码。
头文件 重复包含 前向声明地狱没有 modules 之前C20 Modules 还是半残头文件管理是痛苦之最。
即使 C20/23/26 Modules 来了兼容旧代码的代价巨大实际使用率低。
未定义行为UB密度过高严格别名违规、signed overflow、null 指针解引用、越界、use-after-free 等 UB 太多而且编译器可以随便“假设不发生”然后生成核弹级优化。
这不是单个特性而是整个语言哲学的问题但很多人觉得“默认允许 UB”是最大的设计失误。
如果只能选一个“最不应该存在”的我个人投给数组名到指针的隐式衰退array-to-pointer decay 裸指针作为默认参数/返回类型被允许理由它直接导致了 C 前 30 年 70% 的内存安全 bug现代替代方案span / array / vector / ranges已经非常成熟保留这个规则纯粹是为了兼容 1972 年的 C而这个兼容性代价现在已经远超收益Rust 直接把这个设计砍掉证明了可以砍而且砍了之后世界更美好Bjarne Stroustrup 本人怎么看他公开说过几次“后悔”或“如果重来”的点从访谈/论文中没有在早期就强制更强的类型安全模板语法太复杂concepts 晚了十几年允许太多的隐式行为和兼容 C 的代价但他也反复强调“没有哪个主要特性是应该完全删除的”因为它们都有历史价值和使用场景。
结论2026 年视角C 最不应该存在的特性其实不是某个单一功能而是“为了兼容 C 而保留的大量危险默认行为”这个整体设计决策。
如果能时光倒流大多数现代 C 开发者最想改的可能是“让 C 从一开始就默认更安全而不是把安全当成 opt-in。
”你自己最讨厌 C 的哪个特性是上面这些还是别的更小众的雷比如 union、goto、volatile、exception specifications 等