优化器对堆内存分配的看法
在 C 领域,问题出现了:编译器可以优化堆内存分配吗?让我们深入研究这个有趣的主题。
考虑以下代码片段:
int main() { int* mem = new int[100]; return 0; }
编译器是否有权删除新调用?根据我们的研究,g 和 Visual Studio 回避这种优化,而 clang 则拥抱它。这种差异引出了一个问题:new 是否依赖于底层系统调用,导致编译器优化不切实际且不允许?
编译器的理由
为了澄清这个难题,我们必须承认 N3664 的作用,该提案允许编译器围绕内存分配进行优化。然而,这种优化是在 N3664 之前构思的,引发了对其有效性的质疑。
为了回答这个问题,我们转向“as-if”规则,这是 C 标准的一个基本方面。该规则允许实现偏离特定要求,只要它们保持程序的可观察行为即可。
由于 new 可能会引发异常,从而改变程序的返回值,因此“as-if”规则似乎禁止它的优化。然而,编译器可能认为异常处理是一个实现细节,在这种情况下,不会触发异常。因此,消除 new 调用不会违反“as-if”规则。
此外,“as-if”规则扩展到 new 的非抛出版本。然而,在单独的翻译单元中存在新的替代运算符可能会影响可观察的行为。因此,编译器必须确保不存在这种情况才能安全地执行此优化。
Clang 的激进方法
以前的 clang 版本即使在这种情况下也进行了优化,但后来版本变得更加谨慎。
总之,编译器可以利用优化堆内存分配,包括使用 new 进行的分配。然而,这种优化必须遵守“as-if”规则的细微差别以及 C 异常处理机制的复杂性。
以上是C 编译器可以优化堆内存分配吗?的详细内容。更多信息请关注PHP中文网其他相关文章!