2012-03-19 24 views
1

は、誰もが機能foo1の自動のchar * Qは()は常にP =バーの後に初期化されることを私が保証C++標準での参照に私を指すことができます()foo1()で呼び出されました。私はfoo2()のような新しいブロックを作成するのに慣れていて、最適化コンパイラが過度にブロックされ、編集的になっているのだろうかと思っています。または、私は編集的であると正しく、コンパイラがコードを最適化しないと仮定してはいけません。p = bar()は常により前に呼び出されます。? ありがとう!C++の初期化は

#include <stdio.h> 
#include <stdlib.h> 
#include <strings.h> 


char* bar() 
{ 
    char* t = (char*)malloc(15); 
    strcpy(t, "Hello World!"); 
    return t; 
} 

void foo1(void) 
{ 
    char* p = NULL; 

    printf("foo1: do some stuff\n"); 

    p = bar(); 

    printf("foo1: do some more stuff\n"); 

    char* q(p); 

    printf("foo1: q says:%s\n", q); 

    free(p); 
} 

void foo2(void) 
{ 
    char* p = NULL; 

    printf("foo2: do some stuff\n"); 

    p = bar(); 

    printf("foo2: do some more stuff\n"); 

    // is this block necessary? 
    { 
     char* q(p); 

     printf("foo2: q says:%s\n", q); 
    } 

    free(p); 
} 

int main(int ac, char* av[]) 
{ 
    foo1(); 
    foo2(); 
    return 0; 
} 
+3

あなたは "恐ろしいCコードはC++を装った" wow-を言うことができますか? – Puppy

+1

現時点では標準の特定の部分を指すことはできませんが、探すべきキーフレーズは*シーケンスポイント*です。 –

+0

@標題私は 'char * q = p;'を 'char * q(p);'と書くことを好みます。 'q'と混同しないでください。 'char *' – Mahesh

答えて

2

あなたは安全にp = bar()が原因sequence pointsの存在にchar * q(p)前に発生すると仮定することができます。

私は今、C++標準を通じて苦労する自分自身をもたらすことはできないが、私はあなたに私は十分に安心してあなたの心を置くことを願っていますC99標準から同等、与えることができます:

5.1.2.3を:

、揮発性のオブジェクトへのアクセスオブジェクトを変更、ファイルを変更、またはこれらの操作のいずれかが 実行環境の状態の変化であるすべての副作用、あるん機能 を呼び出します。発現の評価は副作用を引き起こすかもしれない。シーケンス番号は であり、シーケンスポイントと呼ばれる特定のポイントは、前の評価のすべての副作用 が完了し、以後の評価の副作用は発生しないものとします。

附属書C:(強調鉱山)

以下は5.1.2.3に記載された配列の点である:

  • 関数の呼び出し 、後議論が評価されました。
  • 次の演算子の最初のオペランドの末尾は、論理AND &&です。論理OR ||;条件付き?;コンマ,
  • 完全な宣言子の末尾。
  • 完全表記の末尾:イニシャライザ;式は の式です。 選択ステートメント(ifまたはswitch)の制御式。制御式 はwhileまたはdoです。 for ステートメントの各式。 returnステートメントの式。
  • ライブラリ関数が返される直前。
  • 各フォーマット済みの入出力関数に関連付けられたアクションの後に 変換指定子。
  • 直前および 直ちに比較関数への各呼び出しの後、また、比較関数への呼び出し、その呼び出しの引数として渡されるオブジェクト の任意移動 間を。
+1

C++ 11では、 'シーケンス前'と 'シーケンス後'のシーケンスポイントを破棄しています。 – bames53

+0

@ bames53:確かにそうですが、言い回しだけが変更されました。セマンティクスはC++ 03と同じままであることを意図していました。 – ildjarn

+0

ありがとうございました! – Steve

0

C++ 03 6.7/2 "宣言文は、" 言う:自動ストレージ期間(3.7.2)と

変数はその宣言文が実行されるたびに初期化されます。ブロック内で宣言された自動保存期間の変数は、ブロックの終了時に破棄されます。

1

このパラノイドである必要はありません。 C++は、次のフル発現に関連するすべての値の計算とサイド 効果が評価される前に、 フル発現に関連する

すべての値の計算と副作用が配列決定されると言います。

[intro.execution] 1.9/14、n3337

+0

正解の場合+1。なぜN3337を引用しているのですか?つまり、N3290は現在の標準(C++ 11)と同じですが、N3337は次の規格の最初の草案ですか? –

+0

@ Cheersandhth.-Alf:N3290はかなりの期間無料で利用できませんでした。おそらく、単にファイルにはコピーがありません。 – ildjarn

+0

@ Cheersandhth.-Alf n3337は、スタンダードの最初のポストC++ 11ドラフトです。公開されているC++ 11標準のすべての内容を持ちますが、いくつかのタイプミスなどは修正されています。 – bames53