
文章插图
编译器本身也是 C++ 里的一个大魔法 , 编译器的优化可以产生非常巨大的性能差异 , 它对 C++ 带来的性能差异的影响比 C 带来的性能影响要大得多 , 很大程度上是因为程序怎么写造成的 。优化本身一方面能提高性能 , 另一方面会揭露你程序里的短处 , 因为优化的时候 , 你觉得程序这么写没问题 , 可能在没有优化的时候也确确实实没有问题 , 但是一旦打开了优化 , 你会发现程序里突然出了“鬼” , 就是因为你的代码里可能写出了某些未定义行为 。未定义行为在 C++ 里非常妖孽 , 但它对优化来讲也非常重要 。比如空指针的解引用就是一个比较常见的未定义行为 , 当然在大部分现代环境里都有保护模式 , 一旦有非法内存访问 , 包括空指针 , 在用户态执行的程序会立即挂掉 。程序挂掉实际上是件好事情 , 让你立即能够进行调试 , 知道问题出在哪里 。但有很多未定义行为编译器没法发现、没法告警 , 然后在执行过程中你才会突然发现程序行为不正常了 , 你调了半天才发现 , 哦 , 原来我这里触发了一个未定义行为 。
打个比方 , 带符号整数的溢出在 C++ 里就是一个未定义行为 , 你如果认为两个正整数相加有可能会变成负数 , 会翻转的话 , 那就错了 。C++ 编译器有可能会认为这种情况不可能发生 , 这种情况下 , 代码的行为就可能跟你想象的行为会不一样 。编译器会有一些告警选项 , 你还可以使用一些像 clang-tidy 这样的静态扫描工具 , 部分可以解决这些问题 , 但这也只是部分 。你仍然需要了解这些 。如果你不知道这些未定义行为 , 如果你没有打开告警选项 , 如果你也没利用静态扫描器 , 那很可能这些未定义行为会把你坑得很惨 。

文章插图
这是另外一个特殊的编译器的行为 , 编译器对硬件特性的照顾 。它产生的代码会跟你想象的有一点点不一样 。这边有x、y、a三个全局变量 , 看代码 , 比较直观的想象应该是 , 先写x、再写y 。但是我们看一下右边图 , 会发现生成的汇编代码里 , 它先读a , 再写y , 再写x , 这就是编译器为了照顾处理器进行了一个乱序处理 。现代处理器里为了在单个周期能尽量多执行指令 , 内部有流水线 , 可以并行执行多条指令 。把读a和把结果写到x里面 , 这两个操作有依赖关系 , 不能并行 。所以编译器会把写y穿插进去 , 因为这条指令跟读a是不冲突的 , 可以并行执行 。我们可以看到 , 你即使没写任何特殊的东西 , 编译器都可能会做一些乱序 , 而处理器本身也还可能会产生额外的乱序 。
6. 软件——语言抽象性:

文章插图
语言的抽象性 , 这个可能就比较好理解了 , 和比较直白的 C 相比起来 , 在 C++ 里如果写同样的 Obj obj , 除了和 C 相同的步骤之外 , 还会调 Obj 的构造函数 , 当代码在执行到下面的 } , 会调用析构函数 , 这就是一个比较隐式的一个操作 。
- 美甲培训学校如何
- 服装设计培训 服装设计师培训学校
- 学会计 会计培训学校机构
- 英语口语培训 口语培训课程
- 影视摄影师培训学校
- 职业培训 深圳职业培训学校
- 装饰培训机构 装饰设计培训哪里好
- sigill sigikid
- 广州美容学校推荐 广州美甲培训学校地址
- 西安计算机培训机构哪个最好 西安计算机培训学校有哪些
特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
