C++ 复杂性 – 为什么你会觉得 C++ 复杂?

Blog
Author:
Amir KirshAmir Kirsh
Published On:
10月 18, 2021
Estimated reading time:
1 minute

下周,我将在 CppCon 2021 就 C++ 复杂性的话题进行演讲

当然,C++ 是否真的复杂因人而异,但多数人都会认同这一观点。

“为什么你觉得 C++ 复杂”这一问题的答案自然也十分主观,但这是个非常有趣的问题,而且会得到各种不同答案。我们或许会认为:

  • 在教授一些功能时可能需要采取更好的方法
  • 部分领域可能需要经过 ISO 流程优化
  • 一些情况下或许应该采用其他更好的工具

一段时间以来,C++ 复杂性一直是讨论的焦点。Kate Gregory 在 C++17 大会上就此作了一次演讲,演讲题目为:“它就是很复杂”。有人认为复杂就是这门语言的特点,也有人则从文化角度看待这一问题

下面是从 Reddit 讨论中截取的一段内容

complicated-c-code-reddit-discussion

就像我说的,我会在 CppCon 2021 谈论 C++ 复杂性的问题。大约两个月前,我在 CoreCpp 的一场类似的演讲中问观众,他们认为 C++ 复杂的原因是什么?

经过与 C++ 社区成员的协商,我提前准备了一份与该问题相关的清单,并尝试将所有潜在的复杂性因素都列在清单上。以下就是列出的清单——调查对象可以勾选任意数量的选项:

  • 没有——我认为 C++ 中的所有内容都很容易
  • 指针和参考
  • 内存和生命期管理
  • 常量正确性
  • 右值和移动语义
  • 构造函数/析构函数
  • 运算符重载
  • 隐式转换
  • 多重继承
  • 虚拟继承
  • 多态
  • 协变返回类型
  • 异常情况处理
  • Lambda 表达式
  • 模板特化
  • SFINAE
  • 模板问题
  • 智能指针
  • 多线程和并发
  • 无锁算法和内存栅栏
  • 性能
  • 测试
  • 与外部库的使用
  • 保持使用新的 C++ 标准
  • 协程
  • 编译和/或链接
  • 处理较长的构建时间
  • 与外部动态库的使用
  • 封装和部署
  • 调试内存泄漏
  • 调试和故障排除崩溃问题
  • 调试问题
  • 具体 GPU 编程问题
  • 具体实时编程问题

除上述选项外,还有“其他”选项,选择“其他”选项的人需要说明具体原因。

这份问卷还让调查对象填写了他们已使用 C++ 多长时间,包括:0-1 年、2-4 年、5-8 年、9-12 年及 12 年以上。

结果非常有趣。

首先是观众的 C++ 使用经验

years-of-C-experience-Amirs-survey-1

尽管问卷中罗列的复杂性清单已十分详尽,但仍有少数人添加了其他原因,例如:理解编译器错误、管理大项目和缺乏标准工具(比如缺乏标准构建工具)。

清单的其中一个选项为:“我认为 C++ 中的所有内容都很容易”。

选择该选项的人占比为 9%,当然,与初学者(5%)相比,有经验的人所占百分比更高(虽然也只有 15%),如图:

Everything-in-C-is-a-breeze-for-me-

以下是所有选项对应的结果,总共 101 人:

Amirs-survey-entire-sample

排在前五名的分别是:

  1. 调试内存泄漏
  2. 右值和移动语义
  3. 处理较长构建时间
  4. 保持使用新的 C++ 标准
  5. 无锁算法和内存栅栏

不过,在基于使用经验进行分析时,老手和新手眼中的复杂性也有区别。

对于老手而言,排名前五的是:

  1. 无锁算法和内存栅栏
  2. 调试内存泄漏
  3. 保持使用新的 C++ 标准
  4. 处理较长构建时间
  5. 封装和部署

最令老手费解的点:

Top-complexities-veterans-1

对于新手而言,排名前五的是:

  1. 右值和移动语义
  2. 内存和生命期管理
  3. 处理较长的构建时间
  4. 隐式转换
  5. 调试内存泄漏

最令新手费解的点:

Top-complexities-novices-1

值得注意的是,对于老手和新手而言,“处理较长构建时间”都排在前 5 名内,这就意味着这是一个困扰着整个 C++ 行业的问题。当然,Incredibuild 非常乐意为你解决这个问题。业内许多公司也选择了 Incredibuild 的分布式构建加速方案为其业务提供支持。

另外有趣的一点是,“调试内存泄漏”的占比依然很高(35% 的人都选择了该选项),而距离智能指针在业内被广泛接受已经过去很长时间。目前尚不清楚人们究竟是不使用智能指针还是使用方法有误。这一点还需进一步调查。

另一个值得注意的结果是,新手方面,“右值和移动语义”排在前 5 名;而老手方面,该问题的排名也并不低 (第 7)。看来,为了在教授相关内容时使之更容易学习和理解,我们确实还有一些工作要做。

“封装和部署”在困扰老手的问题中排名第 5,似乎我们仍在为 C++ 寻找解决该领域问题的良方,而且也有一些不错的解决方案。

总结

C++ 无论是对新手还是专家而言都有复杂性。但是,当你与 C++ 从业者交谈时,你就能感觉到这些复杂性只是一种挑战,而非 C++ 的全部,也不是寻找其他替代方案的理由(比如 Rust?至少 C++ 爱好者不会这么做)。

随着 C++ 的演变发展,尽管会引入新的复杂性,但许多问题正得以解决。当然,如果我们想为最佳实践、最佳工具以及 C++ 的进一步发展寻找解决方案,了解社区感受到的复杂性也就十分重要。

WhitepaperDownload