4

自動オブジェクト(スタック上に作成されたオブジェクト)の破棄は、スコープ外になる前に実行されることが保証されていますか?

明確にするために:

#include <iostream>

class A {
  public:
    A() {
      std::cout << "1";
    }
    ~A() {
      std::cout << "3";
    }
};

void test123() {
  A a;
  std::cout << "2";
}

を印刷する"2"必要aがなくなったため、理論的には、コンパイラは、a必要がなくなったらすぐに最適化と破棄を試みることができます。

上記の機能を常に印刷することに頼ることはできます123か?

4

3 に答える 3

10

スタックオブジェクトの破棄順序は厳密に定義されています。スコープを離れると、宣言の逆の順序で実行されます(、の終わりから実行するか、{}によってreturn、または例外によって)。だから、あなたはいつもそこに表示さ123れます。

ただし、コンパイラの最適化は「as-if」ルールによって管理されることに注意してください。言い換えると、コンパイラは、結果のプログラムが通常の時間に破棄されたかのように動作する限り、オブジェクトを早期に破棄できます。この場合、出力を行うため、コンパイラーは適切な時間に出力をスケジュールする必要があります。ただし、たとえば、deleteプリミティブ型へのdaポインターがあり、コンパイラーがその値への未解決のポインターが他にないことを証明できる場合は、原則として、それをdelete以前に移動できます。重要なのは、この最適化に気付くことができる適合プログラムがないということです。

于 2011-08-28T20:37:53.027 に答える
4

標準では、そのコードの正しい動作は「123」を出力していると判断されています。コンパイラーは、同じセマンティクス( as-ifルール)を維持しながら、コードを好きなだけ変更できます。ここでコードを並べ替えると、セマンティクスが変更されるため、準拠コンパイラーはそれを行うことができません。

于 2011-08-28T20:38:21.903 に答える
0

コンストラクターには副作用がある可能性があります。たとえば、ミューテックスを実装する場合があります。つまり、コンストラクターがロックし、記述子がミューテックスのロックを解除します。したがって、123が必要です。

于 2011-08-28T20:41:29.327 に答える