2009-03-15 11 views
7

次のコードサンプルでは、​​ '++ i'がメモリ割り当て(operator newを呼び出す)の後、Xのコンストラクタの呼び出しの前に評価されるというC++標準の保証はありますか?新しい式の評価順序は?

new X(++i) 

答えて

12

5.3.4の新

割り当て関数がコンストラクタの引数を評価する前に、またはコンストラクタを評価した後に呼び出されているかどうか

21引数はコンストラクタに入る前に指定されていません。また、割り振り関数がヌルポインターを戻すか、例外を使用して終了するかどうか、コンストラクターへの引き数が評価されるかどうかは不明です。(あいまいさを避けるために)と一緒に

読む:

5.3.4の新

8 new式は、割り当て関数(3.7を呼び出すことにより、オブジェクトのストレージを取得します。 4.1)。 newexpressionが例外をスローして終了すると、解放関数(3.7.4.2)を呼び出してストレージを解放することがあります。割り当てられた型が非配列型である場合、割り当て関数の名前は演算子newであり、割り当て解除関数の名前は演算子deleteです。割り当てられた型が配列型である場合、割り付けは 関数の名前は演算子new []で、割り振り解除関数の名前は演算子delete []です。 [...]

これはほとんど質問に答えます。答えはいいえだ'。

+0

はい、それはかなり明確です:) –

+0

それは速かった。ありがとう! –

+0

私は不確定性を割り振り関数にまで拡張するだけでいいのでしょうか?引数はコンストラクタが呼び出される前に完全に評価されていますか? –

1

++割り当てと呼び出しの前に実行する必要があります。

EDIT:(やや早すぎるかもしれません)

+0

これについての証拠はありますか? –

+0

Hmmm ...これについて考えると、それは((X *)malloc(sizeof(X))) - > X(++ i)と何とかやっていて、もう分かりません。コンパイラはnewFunction(++ i)と同等にする必要があると思いますが、少し急いで答えているかもしれません。 –

+0

Cでは、答えは「はい」です。関数呼び出しの前にシーケンスポイントがあり、その引数を評価する際のすべての副作用が関数が呼び出される前に完了していなければなりません。私はC++でそれを保持すると期待します。 –

2

「新」と一般的には「++ i」の

+0

あなたもそうです..! – Warrior

4

の間にはシーケンスポイントはありません

、C++コンパイラは、それが意味を変更していないとして再次関数のパラメータに無料です。

こちらをご覧マーティンの答え:What are all the common undefined behaviours that a C++ programmer should know about?

は、ボンネットの下ここで起こっ2つの関数呼び出しは、実際にあります。 X

ため

  1. オペレータ新しい
  2. コンストラクタ呼び出しは、2つの別々の呼び出しだにもかかわらず、私はこれらの二つの操作間のシーケンスポイントがあるとは思いません。ウィキペディアはsupport this pointに見えます。したがって、コンパイラは評価が合っていると自由に変更できます。

1

新しいX(++ I)

新しいオペレータWRTのC++標準の構文:

[::] "新しい" [ "(" 表現リスト ")"] {新型-id | "(" タイプID ")"} [ "(" 表現リスト ")"]

したがって、オブジェクトX.

  • 式リストの

    1. 割り当てメモリを渡すことが評価されます割り当てられたオブジェクトのコンストラクタに渡します。

    オブジェクトXのコンストラクタが呼び出される前に、++が評価されることがあります。 n2798の私のコピーから

    乾杯..

  • +0

    これは、どの順序でPARSEDされるかを示しています。どの順序で実行されるのではありません。確かに+私は何かにかかわらず、コンストラクトの前に呼ばれるでしょう)。 –