C 的一年

  • 大约一年前开始再次大量编写 C 代码,如今进行回顾。

    • 起初是实验,想看看会多想念 C++的一些有用特性及能否在不发疯的情况下编写非简单代码库。
  • 用 C 编写的 github 项目:

    • sokol:逐渐增长的平台抽象头文件集。
    • sokol-samples:Sokol 的示例。
    • chips:8 位芯片模拟器。
    • chips-test:芯片模拟器的测试和示例,包括一些完整的家用计算机模拟器(不含声音)。总共约 32k 行代码(不包括第三方代码)。
  • 学到的几点:

    • 挑选适合问题的语言:不再试图用单一语言解决所有问题,而是学习多种语言并选择适合的,将 C 加入语言工具箱对 C++过于复杂的问题是好决策,C 比 C++更易与其他语言集成,当前语言工具箱包括 Python(用于跨平台脚本等)、Typescript(用于前端相关)、C(写库等)、C++(大代码库等),还关注一些“更好的 C”语言如 Nim、Zig、Ion 等。
    • C 是 WebAssembly 的完美匹配:用 C 编写的 WebAssembly 演示比用 C++编写的小很多,如 sokol-gfx 三角形示例仅 22KByte 下载。
    • C99 比 C89 有巨大改进:曾想让 sokol-headers 完全符合 C89 标准,后发现实际用的 C 并非纯正 C89,现在使用 C99 的一个子集在三大编译器上都能编译,C99 最大改进是指定初始化,很简单优雅且有用。
    • 指针和显式内存管理的危险被高估:需注意 API 设计,原始指针作为堆对象所有者危险,C++智能指针可帮忙,但指针作为分配所有者本身就是错误概念,sokol-gfx API 不返回指针,内部动态内存管理很少,32k 行 C 代码中只有 13 次 malloc 调用,8 位模拟器代码中无 malloc 或 free 调用。
    • 更少的样板代码:写 C 代码比写典型 C++代码花费在写无意义样板上的时间少,C 没有 RAII,若像 C 应有的那样使用(数据都是 POD,复制可简单内存复制,销毁无需动作),就不需要构造、析构等操作符的代码,只需在需要时为结构体成员定义默认值。
    • 更少的语言特性焦虑:写 C 代码更平静专注,C++有多种方式做事需做很多微决策,会养成一些不良习惯,而 C 简单,写 C 代码时每一行都有用,不用担心选对语言特性。
  • 结论:“C 实验”成功,很多问题选择 C 比 C++好,C 更简单,虽有一些旧 API 设计问题,但可通过精心设计 API 解决,且 C99 应能在 C++中使用。
阅读 7
0 条评论