为什么 -O0 不能禁用 gcc 编译优化?

Why can't -O0 disable gcc compile optimization?

本文关键字:编译 优化 gcc -O0 不能 为什么      更新时间:2023-10-16
string str="fujian";

有些书说代码会触发复制构造函数,但g++会对其进行优化,使复制构造函数不会被调用。

然而,我使用g++命令- 0来禁用优化,但它仍然不能触发复制构造函数。

如何理解?

对于GCC和Clang,您可以使用-fno-elide-constructors编译标志来关闭复制/移动省略优化。

复制省略规则基于ISO c++ 12.8。虽然通常用于优化的其他规则在第1条中统称为"as-if"规则(它允许实现生成的程序的行为与基于抽象机器模型的"非优化"程序语义有所不同),但此规则非常特殊,您可以将"优化"代码本身的行为与原始含义一样精确。换句话说,省略的构造函数调用可能根本不存在于抽象机器的行为中。

如果没有未定义行为,无论是否根据as-if规则进行优化,优化后的程序和未优化的程序的可观察行为应该是相同的(尽管它们可能在性能等方面有所不同)。然而,复制省略更具侵略性,也就是说,它可以改变可观察的行为。

你最好不要依赖于复制省略产生的差异。因此,对于普通的优化选项保持相同的行为,并为了解风险并且确实需要的用户提供单独的选项来控制精确(不同)的行为是合理的。

WG21/N4296

1.9程序执行 一个执行格式良好的程序的一致性实现应该产生相同的可观察到的行为作为抽象机的对应实例用同一程序执行的一种可能同样的输入。但是,如果任何此类执行包含未定义的操作,则本国际标准对使用该输入执行该程序的实现没有要求(甚至没有)(关于第一个未定义操作之前的操作)

一个符合要求的实现的最低要求是:

(8.1) -对易失性对象的访问严格按照抽象机的规则求值。

(8.2)—在程序终止时,写入文件的所有数据应与下列任一可能结果相同根据抽象语义执行程序将产生。

(8.3)—交互设备的输入和输出动态应以如下方式进行输出实际上是在程序等待输入之前交付的。什么是互动设备是由实现定义的。

这些统称为程序的可观察行为。[注:更严格的通信抽象语义和实际语义之间可以由每个实现定义。-end note]

12.8复制和移动类对象

31当满足某些条件时,允许实现省略类的复制/移动构造对象,即使为复制/移动操作选择了构造函数和/或对象的析构函数有副作用。在这种情况下,实现处理省略的复制/移动的源和目标操作就是引用同一对象的两种不同方式,以及该对象的销毁发生在时间的后期,如果没有优化,两个对象就会被破坏这种复制/移动操作的省略,称为复制省略,在以下情况下是允许的(其中可以组合以消除多个副本):