带你读《2022技术人的百宝黑皮书》——19条跨端cpp开发有效经验总结(1)https://developer.aliyun.com/article/1340929?groupCode=taobaotech
代码文件格式
在跨终端开发中, 特别是包含中文的部分, 除非你的代码都是英文注释, 否则很难避免在多平台下( 特别是windows与类unix平台下的开发)交叉开发带来的中文乱码问题。
建议:全部使用UTF-8 BOM编码格式。
关于内联函数
定义:当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用。
参考定义,自然他的优点,在函数体比较小的情况下,内联该函数可以令目标代码更高效,通常情况下,应该鼓励在函数比较短时使用内联。
关于内联函数,或许很多非跨端程序员或认为不足为重,其实这里有几个非常值得在跨端开发被重视的问题:
- 过度的内联,会导致程序臃肿,特别是对于移动端,一方面c++代码的体积问题一直不能很好的得到解决,另一方面也会使得程序变慢。
- 在导出头文件中非恰当的使用内联,会导致在跨模块开发中带来意向不到的结果。这里举个例子,在提供跨终端SDK时,通常会提供导出头文件,但是如果在导出头文件里不恰当的内联,将使得编译从当前单元跨越到另外一个模块,可能会引发一系列问题
- 尽管编译器对内联函数都有或多或少优化,但是不同编译器不尽相同,实践下来良好的内联使用习惯依旧能帮助大家,譬如,我们在移动端的某个cpp项目中,通过去内联,减少了一定的包大小,实践证明编译器在择优选择的过程中不一定会完美契合。关于内联的编译器优化可以参考:https://isocpp.org/wiki/faq/inline-function
综上在跨端开发中因尽量避免使用内联,这里给出几个可以衡量的准则(经验值?):
- 行数超过10行禁止使用内联(google 建议)
- 在非get函数里禁止使用内联(经验值, 这一条争议会比较大,但在我看来只有在get某成员变量值时使用内联是有必要的,其他都没有必要且可能会带来“惊喜”)
- 内联函数务必要有适当的修饰符(const)
- 析构函数如果有自定义内容,禁止使用内联(google 建议,通常析构函数远比你想想的做的要多)
关于基础类型定义
请使用基础类型定义,禁止使用自定义基础类型。
看过团队的几个代码库,在基础类型的使用上有些同学甚至三方库也非常喜欢自定义,譬如
typedef std::int8_t int8; typedef std::int16_t int16; typedef std::int32_t int32; typedef std::int64_t int64; typedef std::uint8_t uint8; typedef std::uint16_t uint16; typedef std::uint32_t uint32; typedef std::uint64_t uint64;
在进行跨模块开发以及代码融合时,这些基础类型的自定义经常会出现歧义,redefine等等,或许你会说这样的定义应该要有自己的#define保护,但是大多数程序员不会这么做,这里强烈不建议自定义基础类型,标准库提供的已经足够简略和通用,请方便自己开发的时候同时照顾下团队同学。
CHAR的定义
char的定义需要显示是unsigned还是signed。
需要注意的是,char在标准中不指定为signed或unsigned,不同的编译器可能会有不一样的结果,在发生隐式转 换时可能会有超出期望的结果,譬如,char强转int时,发现在x86平台下是按照有符号处理的,但是在ARM32下被当成了无符号导致问题,ARM64正常有符号,当然你可以通过指定CFLAG += fsigned-char 来解决,但是此类问题应当在规范时就被避免掉。
带你读《2022技术人的百宝黑皮书》——19条跨端cpp开发有效经验总结(3)https://developer.aliyun.com/article/1340927?groupCode=taobaotech