顺着一个点聊:你说"C几乎没有隐藏的抽象,写下的每一行基本都对应真实的指令和内存布局",从某种角度看这个判断值得商榷。
C标准定义的从来不是真实硬件,而是一台"抽象机器"(abstract machine)。编译器只要在可观察行为上等价,内部怎么优化都行,这就是著名的as-if规则。所以你写的for循环,编译器可能直接展开成向量指令;你以为的"一行一条指令",到了机器码那层早就不对应了。我们感受到的"清晰",是C语法层面上的清晰,不是它和硅片之间的一一映射。
更隐蔽的一点是,C自己就藏着不少抽象,只是藏的方式和高级语言不同。比如整数提升(integer promotion):两个char相加,中间会先被提升成int再算,这个转换对很多人是"看不见"的。还有求值顺序、结构体里的对齐填充(padding)、未定义行为(UB)——UB尤其反直觉,一段"看起来能跑"的代码,新版本编译器可能因为它属于UB就整个优化掉。这些不叫"粉黛",但确实是抽象,而且比语法糖还难察觉。
所以我觉得"C的干净"更像是一种"边界清晰的小工具"给人的自由,而不是"完全透明"。它把内存和指针交到你手里,但类型大小、对齐、求值顺序这些,依然是"实现定义"(implementation-defined)的,跨平台时照样得查文档。
不过你那个核心感受我挺认同的:框架半年一换,一门1972年的语言还能让你"心里有底",这种确定性本身就很稀缺。你平时写C是拿来练手,还是真有项目在跑?