多年C++开发使用经验总结

栏目: C++ · 发布时间: 6年前

摘要 借着公司内和其他小组的一个分享,把自己几年来C++开发的一点思考总结一下。全篇没有高屋建瓴的观点,基本都是些细节方面的注意事项。希望能给大家提供一点帮助。 构建工具 C/C++世界里有不少的构建工具:make、autotools、scons、CMake、Bazel。但近几年比较流行的,也就是CMake和Bazel。所以这一部分,也就大概对比下这两个 工具 吧。 究竟该选择哪个工具,我觉得可以从如下几个方面来对比一下: 1、上手难度 因为Bazel采用了类似 Python 的语法,所以其学习曲线相比CMake要平缓一些。但当我们考虑上手难度时,除了学习曲线之外,还要考虑文档的完备性、该工具的通用性等各个角度。当综合考虑时,我觉得CMake是一个尽管保守但仍旧不错的选择。主要原因就在于,CMake几乎已经成为现在C++的事实标准。使用CMake,就意味着: 你可以把你熟悉CMake的技能用在折腾别的C++项目上。而这点之所以重要,是因为你在利用某个第三方库的时候,往往需要大概研究下它的编译过程。 CMake的官方文档和stackoverflow上的问答也比较完善。一旦遇到一个问题,往往通过搜索引擎能快速的得到答案。 另外,从设计理念上来看,CMake提供的解决方案是改革式的:它并没有提供一个全新的解决方案,而是和Make、Visual Studio或者其他现有的构建工具来结合使用的。而这就使得你无需丢弃在其他工具上所积累起来的开发经验——例如你熟悉make工具,哪怕是一个CMake维护的项目,你也可以毫不费力就知道如何来查看编译参数,以及控制编译并发度等等。 而对于Bazel则不是如此。Bazel完全以革命者的姿态完整提供了一整套解决方案,所有的使用细节你都要从头开始。加上文档的匮乏,这就使得你也得花上一段时间,才能熟悉Bazel。 2、thirdparty的管理 Bazel内置了对thirdparty源码级别依赖的支持https://docs.bazel.build/versions/master/external.html: thirdparty可以是用Bazel构建的,也可以不是。对于非Bazel项目,你需要额外为其添加一个Bazel的描述文件。 thirdparty可以是一个本地项目,也可以是一个git仓库或者http链接 所以总的来看,Bazel对thirdparty支持还是非常友好的。 就这点对比来看,CMake其实做的是不太好的。CMake尽管也有ExternalProject https://cmake.org/cmake/help/latest/module/ExternalProject.html的feature,但根据实际经验来看,使用和维护都比较的复杂。所以我还是更倾向于写几个脚本来下载和编译这些thirdparty依赖。 这里可以拿我参与维护的Pegasus https://github.com/XiaoMi/rdsn/tree/master/thirdparty项目为例。在该项目中,我们依赖了几个不同类型的项目: 从构建工具上来看,这些依赖有使用CMake的,有使用make的,有使用autotools的 从来源上来看,有的依赖来自git仓库,有的来自http链接,有的则是从一个大的项目里面挑选了一个更小的模块使用 从代码的使用方式上来看,有的是直接拿来用,有的还需要稍微修改下源代码。 而通过 shell 脚本,这些各种各样的场景我们都能非常方便、直接、易维护的得以支持。 3、其它 Bazel和CMake当然还有些其它方面值得对比,但并非一些通用的点,这里就简单列举下,不再详细展开了: IDE集成 缓存编译结果,从而加速编译过程 多语言混合变成的支持 分布式编译 跨平台的支持 再补充一个别人的讨论Q群:731611386 编程规范 强烈推荐Google C++ Style:https://google.github.io/styleguide/cppguide.html。尽管它禁止了很多C++ feature而被很多人黑的很惨,但从工程的角度而言,它的确提供了非常多极其中肯的建议。说到底,编程规范的存在,主要就是可以让水平参差不齐的工程师们,可以在一起协作出风格较为一致的项目来。 也存在一些工具可以对google规范进行检查: clang-format https://clang.llvm.org/docs/ClangFormat.html cpplint https://github.com/cpplint/cpplint 因为google的规范文档对C++ feature的取舍原因讲的非常好,这里就不再赘述了。唯一想补充的是异常: C++在语法层面对异常支持不太友好:你无法通过函数签名来得知一个函数到底会抛出哪些异常。例如: void GetSomeResource(const char* resource_name); 如果这个接口没有良好文档或注释,并且也没有代码可翻时,你在调用这个接口时很有可能会漏掉一些错误情况——因为它可能抛出异常。更要命的是,一个疏于捕获的异常一旦触发,线上的程序就会crash。 其实解释这么多,大家只要和 Java 中的异常机制对比一下,就高下立判了。对于这个话题,王垠的这篇博客http://www.yinwang.org/blog-cn/2017/05/23/kotlin值得一看的。 在运维Pegasus项目时,遇到过一个老版本glibc的bug:如果多个线程同时抛出异常,程序会陷入死循环。这个bug的发现也是个有趣的过程,后面我专门写篇文章展开吧。 在禁用异常后,程序就只能用错误码来进行错误处理。对于很多项目,大家都采用一套类似的范式,可以参考tensorflow的做法https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/lib/core/status.h C++的新特性 如果能使用C++的新特性,当然是尽量使用的好。我自己在开发中,觉得非常方便必须使用的新特性有: 智能指针 右值,以及C++14中右值得capture lambda, bind initialize list 想补充说一下的是auto,我自己不是特别喜欢这个feature,也非常赞同google规范中的对auto的限制:仅当可以提高代码可读性时,使用auto 这里不由得就想扯起java 10中的var。虽然能方便开发,但觉得更多的是会被滥用。而一个可能被滥用的feature,还不如没有的好。 第三方utility 在做项目开发的时候,一般会有很多琐碎的需求,从而也需要很多utility工具包。这里把我遇到的一些需求整理一下: 算法和数据结构:stl, boost 错误码管理:参见tensorflowhttps://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/lib/core/status.h C语言的字符串封装:string_view https://github.com/abseil/abseil-cpp/blob/master/absl/strings/string_view.h 字符串的各种操作、转换、打印:可以多翻翻abseil https://github.com/abseil/abseil-cpp, 以及folly https://github.com/facebook/folly,另外也推荐fmtlibhttps://github.com/fmtlib/fmt 线程安全的、无锁的数据结构、线程池: folly google全家桶:gtest,gflags, glog, protobuf, grpc 最后,也推荐下kudu这个项目,里面有自己实现的一些工具包https://github.com/cloudera/kudu/tree/master/src/kudu/util,以及对google开源项目中utility的整理https://github.com/cloudera/kudu/tree/master/src/kudu/gutil。 单元测试 每个 程序员 都讨厌写测试。就我自己而言,我觉的单元测试的目的有以下几个: 确保功能的实现和预期一致 防止程序在重构的时候出问题 给模块的使用者,提供使用示例 值得一提的是,对于C++项目,除了功能性测试之外,你最好还能让你的单元测试通过一些自动化工具的检测,如: valgrind:检查内存泄露,以及非法访存 Address Sanitizer:检测非法访存https://github.com/google/sanitizers/wiki/AddressSanitizer Thread Sanitizer:检测线程竞争https://clang.llvm.org/docs/ThreadSanitizer.html 写在最后 自己的整理这些内容时,脑子里反复萦绕的一个问题是:我们在开发一个项目时,所要遵守的各种流程和规范到底是不是真的有必要的?说的更直白一点就是,“代码洁癖”这东西到底有没有意义? 我的看法是:代码洁癖不是一个原则,而是在投入和产出上的一种权衡。如果仅仅快速试错,那么就不需要维持代码洁癖,因为你完全不知道你今天写的代码究竟能存活多久。而如果是一个马拉松式的项目,代码洁癖就值得维持,因为它对于项目的维护的确很有意义。 最后,贴一个 C语言 学习交流群:731611386 以上为今天的分享内容,谢谢大家!


以上所述就是小编给大家介绍的《多年C++开发使用经验总结》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Security, Privacy and Commerce, 2nd Edition

Web Security, Privacy and Commerce, 2nd Edition

Simson Garfinkel / O'Reilly Media / 2002-01-15 / USD 44.95

Since the first edition of this classic reference was published, World Wide Web use has exploded and e-commerce has become a daily part of business and personal life. As Web use has grown, so have ......一起来看看 《Web Security, Privacy and Commerce, 2nd Edition》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具