2

私がこの架空の、奇妙で直感的でない状況にあるとしましょう

    #include <iostream>

    struct A
    {
      A()
      {
        member = 1;
      }

      A(const A &)
      {
        member = 2;
      }

      int member;
    };

    int main()
    {
      A a = A();
      A b = a;
      std::cout << a.member << std::endl;
      std::cout << b.member << std::endl;
      return 0;
    }

aコピーの省略とは、デフォルトのコンストラクターだけで初期化され、bはコピーコンストラクターで初期化されることを意味します。また、(少なくともgccでは)コピーの省略を行わないようにコンパイラーに指示できることも知っています。

私の質問は、コンパイラがこのクラスのためだけにコピーの省略を使用しないようにする方法がありますか?

実際の状況での答えは、99.9%の確率で他の方法を見つけることであり、0.01%のケースはありません(これは実際の架空の質問であり、「架空の質問」ではありません)。

4

2 に答える 2

5

コピーの省略は標準で許可されており、 As-Ifルール[#1]に従う必要がないのは単一の最適化であるため、この動作に依存しないでください。

gccの場合のように、manページからいくつかのコンパイラ設定を使用できます。

-fno-elide-constructor

C ++標準では、同じタイプの別のオブジェクトを初期化するためにのみ使用される一時オブジェクトの作成を実装で省略できます。このオプションを指定すると、その最適化が無効になり、G++はすべての場合にコピーコンストラクターを呼び出すように強制されます。

ただし、これを使用すると、コードが異なるコンパイラ間で移植できなくなります。


[#1] C ++ 03 1.9 "プログラムの実行:

抽象マシンの観察可能な動作を(のみ)エミュレートするには、準拠する実装が必要です。

脚注はそれをさらに詳細に説明しています。

この規定は、「あたかも」ルールと呼ばれることもあります。これは、観察可能な動作から判断できる限り、結果が要件に準拠しているかのようである限り、実装はこの国際規格の要件を自由に無視できるためです。プログラムの。たとえば、実際の実装では、その値が使用されておらず、プログラムの観察可能な動作に影響を与える副作用が発生していないと推測できる場合、式の一部を評価する必要はありません。

于 2012-03-31T16:34:48.923 に答える
3

RVO / NRVOは、標準および一般的にはGoodThing™によって明示的に許可されており、RVO / NRVOによって破られる優れた設計はほとんどないため、コンパイラー作成者がそのようなオプションを実装する理由はありません。

ケースバイケースでオフにできるコンパイラはありません。

于 2012-03-31T16:35:55.870 に答える