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

时间:2013-04-27 14:20:14

标签: c++ string g++

string str="fujian";

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

但是,我使用g ++命令-O0来禁用优化,但它仍然无法触发复制构造函数。

如何理解?

2 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:1)

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

如果没有未定义的行为,根据as-if规则进行优化或不进行优化,优化程序和非优化程序的可观察行为应该相同(尽管它们可能有所不同)表演等)。但是,复制省略更具侵略性,即它可以改变可观察的行为。

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

WG21 / N4296

  

1.9程序执行

     

5执行格式良好的程序的符合实现应产生相同的可观察行为   作为具有相同程序的抽象机的相应实例的可能执行之一   和相同的输入。但是,如果任何此类执行包含未定义的操作,则此国际   标准不要求使用该输入执行该程序的实现(甚至不是   关于第一次未定义操作之前的操作。)

     

8符合实施的最低要求是:

     

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

     

(8.2) - 在程序终止时,写入文件的所有数据应与其中一个可能的结果相同   根据抽象语义执行程序会产生。

     

(8.3) - 交互设备的输入和输出动态应以提示的方式进行   输出实际在程序等待输入之前传送。什么构成了交互设备   是实现定义的。

     

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

     

12.8复制和移动类对象

     

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

     

...