C++作为语法最复杂、写代码时最需要思前顾后的语言,我们不在身边随手备用几个“大杀器”在线工具,可能真的不是很利于工作的开展呐。
相信大家对下面这两个网页已经非常熟悉了,它们是编写代码过程中必不可少的工具宝典。
1. cppreference
2. cplusplus**
上述两个网页主要是提供非常详尽的语法层面的资料。
除此之外,我将从其他各个方面给大家推荐几个相对小众但是非常实用的在线工具。
相信我,接触了这几个工具后,你一定会爱上它们的。
实用在线工具 ✦
首先,这几个工具具备如下的通用功能
01 设置运行平台、编译器及版本
x86、x64、arm
gcc、clang
7.5.0、9.4.0,etc
02 设置C++语言版本
c++11、c++14,etc
03 设置编译优化选项
Og、O1、O2,etc
下面,我将结合自己的使用经验,依次介绍这几个工具的典型应用场景和使用效果。
从编译器的角度看源码
这就是C++ Insight
我们在写代码的时候,如果不是对C++标准和编译器了如指掌,可能很难知道编译器在底下到底做了什么。使用C++ Insights,可以帮我们一探究竟。
使用花括号初始化,编译器保证了所有的成员函数都会被(递归地)初始化。
帮助我们一览C++ 14的generic lambda expression 是怎么被编译器展开的。
展示了编译器在用户不自定义构造函数时,会自动生成对应的构造函数(到这里一切正常)。
这里仅仅是在原有代码中新增了一个默认析构函数,如果没有看到编译器生成的代码,可能很难想象移动构造函数根本不会生成吧?原因是什么呢?可以自行搜索一下 rule of five 和 rule of zero。
具体到这个例子,因为如果你的类里面只声明了自定义的/默认的 copy (ctor & assignment operator) 或者 destructor,那么他们会 suppress 编译器生成默认的 move (ctor & assignment operator) 。
结合C++ Insights,我们可以很方便地体会模板参数匹配和引用折叠。
实时汇编分析
这就是大名鼎鼎的Compiler Explorer
它主要用来做实时汇编的生成,帮助我们快速分析代码片段在不同设置下的汇编代码生成,快速提供代码优化方向,并阻止我们自作聪明地去优化代码,感受编译器的强大。
上面两张图告诉我们不要在现代编译器面前班门弄斧……
clang 真是威力无穷啊,直接返回了编译器的结果。
上面两张图展示了对比开启和关闭copy elision后,函数按值返回的汇编结果。
限于篇幅限制,大家可以自己写一些其他的代码试验一下。
通常而言,在分析代码的时候,结合 C++ Insights 和 Compiler Expolrer 会有非常好的效果。
Run-time Benchmark
这就是基于Google Benchmark的Quick C++ Benchmark
我们可能经常需要对一些代码片段进行性能测试,但是由于测试数据的准备比较麻烦或者难以保证覆盖度,为了快速探究不同方案的性能差异,我们可以选择使用它。
在使用 std::string 的时候,我们经常会忽略它在返回值和返回引用时候的性能差异。
回到第一个工具的最后一个例子,这里通过 Quick C++ Benchmark结合更详尽的代码来展示一些语言细节带来的显著性能问题。
可以看到,一个无意间的默认析构函数的定义,可能对代码的性能存在意想不到的影响。
同时,我们可以在由 C++ Insights 生成的结果(“肝”到了晚上,背景都变成了夜间模式)中得到印证。
更进一步,通过 Compiler Expolrer,我们可以直接从汇编层面看清楚调用关系。
【划重点】可以遵从rule of zero的时候,请一定遵从。
当我们注释掉 Test1 的默认析构函数后,在误差范围内,可以看到,两者的性能已经一致了。
这三个工具具备非常好的关联性,可以从 C++ Insights 和 Quick C++ Benchmark跳到另外两个工具中去。
除了上述提到的这些在线工具以外,还有很多其他好用的工具,例如 Compare C++ Builds、OnlineGDB 等等。前者可以帮助我们比较不同代码的编译速度,后者可以提供在线的单步调试环境。由于篇幅限制和相对小众,这里就不再赘述了。
同时,大家可以看到,上文重点介绍的这些在线工具,都可以从不同的角度提供性能分析和优化的方向,大家可以慢慢体会和感受。
本文旨在抛砖引玉,给大家提供一些在线工具的视角。限于作者水平问题,文中肯定有不少遗漏和错误指出,希望大家不吝指正。
文中的示例代码在下方图片里展示啦~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。