返回信息流rt,先谢过前辈们!
这是一条镜像帖。来源:北邮人论坛 / cpp / #101934同步于 2022/5/23
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
国内C++就业应该首选参考什么编码规范呀?
LChen
2022/5/23镜像同步40 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
编码规范共同的作用就是鼓励良好实践、避免错误实践。但是,具体到每个规范,业界每个编码规范都有它的背景。
比如Google的编码规范,其实很守旧,因为谷歌内部有大量的遗留代码。比如他们根本不使用C++异常,因为要使用异常的话,大多数数据应该是“异常安全”的(即如果当前函数没有正常返回,各个局部变量的数据结构也起码应该把自己分配出去的内存释放掉、打开的文件关上……),而Google大量的遗留代码估计都不是异常安全的。(注:标准库里的容器比如vector什么的,所有的方法都支持“强异常安全”,也就是如果一个方法发生异常,结果就好像什么都没发生一样。很强大。)
另外一些业界编程规范,比如汽车工业的AUTOSAR、MISRA、航空工业的JSF等,对可靠性有很高的要求,所以会制定得相对保守,这个一定要做,那个不让做。比如要求必须使用长度明确的整数类型,如int32_t、int64_t,而不是int、long,而且所有的运算都要检查整数溢出,因为整数溢出对于这种高可靠性应用来说很要命。又如,禁止在子表达式中赋值,if和else后面都必须加大括号,禁止使用union,禁止菱形继承。上述做法虽然都不违反C++语法语义,但由于使用起来很容易出错,这些规范宁愿不使用这些特性,来换回一些可维护性。还会考虑通常应用程序员不会考虑的问题,比如栈溢出、stack unwinding的速度等。
再有的就是一些老程序员制定的了,受制于老旧的编程实践,完全忽视摩登C++语言以及编译器特性。比如要求所有的switch都加default,明显是不知道C++17的[[std::fallthrough]];又如,禁止使用构造函数,强迫“两步法”构造对象,要求每个语句都要检查错误,明显是对异常处理有畏惧,知道构造函数不能返回错误码,又不敢抛异常;又如,要求写if(1==x)而不是if(x==1)的,是明显不知道编译器会帮你检查if(x=1)这种简单的错误;又如要求每个函数、类开头标明作者和创建日期,要求每次修改代码都要加注释说是谁改的,明显是不知道版本控制器可以帮你记录代码的每次修改(试试git blame);又如要求写“int a = foo(bar(x));”而不是“int b = bar(x); int a = foo(b);”,号称可以节省一个变量、省内存,明显是不知道现代编译器是怎么做优化的。
还有的就是各个公司机构的官僚主义了,比如要求每个函数最多50行,每个内联函数最多10行,每个文件最多1000行等。对于无能的管理者来说,他们不懂技术,能看懂的就只有数字了。你跟他说“这个函数重复太多,可以提取公共函数,可以用模板,可以用回调……”,他听不懂;你说“这个函数有51行,超过了50行”,他就懂了。
如果你只是想提高自己的C++水平,让自己的编程风格更接近摩登的实践,我推荐C++之父主编的C++ Core Guidelines: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines 这个编程规范并不是哪个具体行业的规范,而是通用的C++规范。它很注重普及摩登C++的特性(现在都2022年了,C++11、C++14、C++17早已不是新鲜事物了,C++20也已经稳定了),读读它,就会发现曾经不好做的事,现在有了很多新方法。
太强了,十分感谢!
【 在 nuanyangyang 的大作中提到: 】
: 编码规范共同的作用就是鼓励良好实践、避免错误实践。但是,具体到每个规范,业界每个编码规范都有它的背景。
: ............
大佬。有没有cpp的学习路线[ema1]
【 在 nuanyangyang (暖羊羊) 的大作中提到: 】
: 编码规范共同的作用就是鼓励良好实践、避免错误实践。但是,具体到每个规范,业界每个编码规范都有它的背景。
: 比如Google的编码规范,其实很守旧,因为谷歌内部有大量的遗留代码。比如他们根本不使用C++异常,因为要使用异常的话,大多数数据应该是“异常安全”的(即如果当...
: ...................
太牛了
【 在 nuanyangyang 的大作中提到: 】
:编码规范共同的作用就是鼓励良好实践、避免错误实践。但是,具体到每个规范,业界每个编码规范都有它的背景。
:比如Google的编码规范,其实很守旧,因为谷歌内部有大量的遗留代码。比如他们根本不使用C++异常,因为要使用异常的话,大多数数据应该是“异常安全”的(即如果当前函数没有正常返回,各个局部变量的数据结构也起码应该把自己分配出去的内存释放掉、打开的文件关上……),而Google大量的遗留代码估计都不是异常安全的。(注:标准库里的容器比如vector什么的,所有的方法都支持“强异常安全”,也就是如果一个方法发生异常,结果就好像什么都没发生一样。很强大。)
:另外一些业界编程规范,比如汽车工业的AUTOSAR、MISRA、航空工业的JSF等,对可靠性有很高的要求,所以会制定得相对保守,这个一定要做,那个不让做。比如要求必须使用长度明确的整数类型,如int32_t、int64_t,而不是int、long,而且所有的运算都要检查整数溢出,因为整数溢出对于这种高可靠性应用来说很要命。又如,禁止在子表达式中赋值,if和else后面都必须加大括号,禁止使用union,禁止菱形继承。上述做法虽然都不违反C++语法语义,但由于使用起来很容易出错,这些规范宁愿不使用这些特性,来换回一些可维护性。还会考虑通常应用程序员不会考虑的问题,比如栈溢出、stack unwinding的速度等。
:再有的就是一些老程序员制定的了,受制于老旧的编程实践,完全忽视摩登C++语言以及编译器特性。比如要求所有的switch都加default,明显是不知道C++17的[[std::fallthrough]];又如,禁止使用构造函数,强迫“两步法”构造对象,要求每个语句都要检查错误,明显是对异常处理有畏惧,知道构造函数不能返回错误码,又不敢抛异常;又如,要求写if(1==x)而不是if(x==1)的,是明显不知道编译器会帮你检查if(x=1)这种简单的错误;又如要求每个函数、类开头标明作者和创建日期,要求每次修改代码都要加注释说是谁改的,明显是不知道版本控制器可以帮你记录代码的每次修改(试试git blame);又如要求写“int a = foo(bar(x));”而不是“int b = bar(x); int a = foo(b);”,号称可以节省一个变量、省内存,明显是不知道现代编译器是怎么做优化的。
:还有的就是各个公司机构的官僚主义了,比如要求每个函数最多50行,每个内联函数最多10行,每个文件最多1000行等。对于无能的管理者来说,他们不懂技术,能看懂的就只有数字了。你跟他说“这个函数重复太多,可以提取公共函数,可以用模板,可以用回调……”,他听不懂;你说“这个函数有51行,超过了50行”,他就懂了。
话说[[fallthrough]]和default有什么关系?
【 在 nuanyangyang 的大作中提到: 】
: 编码规范共同的作用就是鼓励良好实践、避免错误实践。但是,具体到每个规范,业界每个编码规范都有它的背景。
: 比如Google的编码规范,其实很守旧,因为谷歌内部有大量的遗留代码。比如他们根本不使用C++异常,因为要使用异常的话,大多数数据应该是“异常安全”的(即如果当前函数没有正常返回,各个局部变量的数据结构也起码应该把自己分配出去的内存释放掉、打开的文件关上……),而Google大量的遗留代码估计都不是异常安全的。(注:标准库里的容器比如vector什么的,所有的方法都支持“强异常安全”,也就是如果一个方法发生异常,结果就好像什么都没发生一样。很强大。)
: 另外一些业界编程规范,比如汽车工业的AUTOSAR、MISRA、航空工业的JSF等,对可靠性有很高的要求,所以会制定得相对保守,这个一定要做,那个不让做。比如要求必须使用长度明确的整数类型,如int32_t、int64_t,而不是int、long,而且所有的运算都要检查整数溢出,因为整数溢出对于这种高可靠性应用来说很要命。又如,禁止在子表达式中赋值,if和else后面都必须加大括号,禁止使用union,禁止菱形继承。上述做法虽然都不违反C++语法语义,但由于使用起来很容易出错,这些规范宁愿不使用这些特性,来换回一些可维护性。还会考虑通常应用程序员不会考虑的问题,比如栈溢出、stack unwinding的速度等。
: ...................