2011-02-02 11 views
2

は、すべての宣言は(Cで)コンパイル後の関数の先頭に起こるのだろうか?次の例は、私が疑問に思っていることを少し良く示しています。 "ptr1"がうまくいかない場合は、ptr2がNULLに初期化されていると思いますか?範囲内では、すべての宣言はコンパイル後の関数の先頭(C言語)で行われますか?範囲内

int main() 
{ 
    int ret = 0; 

    void * ptr1 = NULL; 
    if (ret = do_ptr_work(ptr1)) 
    goto done; 

    void * ptr2 = NULL; 
    if (ret = do_ptr_work(ptr2)) 
    goto done; 

done: 
    if (ptr1) { 
    free(ptr1); 
    ptr1 = NULL; 
    } 
    if (ptr2) { 
    free(ptr2); 
    ptr2 = NULL; 
    } 

    return ret; 
} 

おかげで、 Chenz

+2

可能な重複:http://stackoverflow.com/questions/2821663/c99-goto-past-initialization – payne

+1

なぜこれを使用する必要がありますか?両方を初期化する場合は、両方の宣言を関数の先頭に移動するのは簡単ではありませんか? – pjc50

+0

合意しました....これは重複しています...ありがとう! (最初の質問に人々を向けるにはどうすればいいですか?) –

答えて

3

いいえ。初期化は、宣言に達すると発生するように定義されています。初期化を飛び越えると、変数は存在しますが初期化されません。

C規格の一要部である§6.2.4:

初期化が オブジェクトに指定されている場合、それは 宣言はブロックの 実行に到達するたびに実行されます;そうでない場合、 値が宣言に到達するたびに 不定となります。

(このテキストは、の自動保存期間がのオブジェクトにのみ適用されます)。

自動記憶域期間を持つオブジェクトのイニシャライザ、及び(ブロックスコープ、 と 通常識別子の 可変長配列宣言子が評価され、値がオブジェクトに に格納されている:別の§6.8ありますそれは ステートメントであるかのように、宣言が実行 順に到達する毎 時間)初期化せずに オブジェクトに不定値を記憶し、宣言子が表示される順序で各宣言 内に含みます。

0

私の好みのために未定義の動作をはるかに近づきすぎるようだし、問題を引き起こすことがバインドされているよう個人的に私は完全にそのアプローチを避けたい、どちらかあなたはに移動したときに別のコンパイラ/プラットフォームを使用するか、メンテナンスプログラマを混乱させるだけです。

理由だけではなく、スコープの開始時に変数を宣言しませんか? とにかく私の目には見えません。

int main() 
{ 
    void * ptr1 = NULL; 
    void * ptr2 = NULL; 
    int ret = 0; 

    if (ret = do_ptr_work(ptr1)) 
    goto done; 

    if (ret = do_ptr_work(ptr2)) 
    goto done; 

done: 
    if (ptr1) { 
    free(ptr1); 
    ptr1 = NULL; 
    } 
    if (ptr2) { 
    free(ptr2); 
    ptr2 = NULL; 
    } 

    return ret; 
} 

また、リファクタリングしても完全に後藤を削除できますか?

int main() 
{ 
    void * ptr1 = NULL; 
    void * ptr2 = NULL; 

    int ret = do_ptr_work(ptr1); 

    if (!ret) 
    ret = do_ptr_work(ptr2); 

    // Tidy up... 
    if (ptr1) { 
    free(ptr1); 
    ptr1 = NULL; 
    } 
    if (ptr2) { 
    free(ptr2); 
    ptr2 = NULL; 
    } 

    return ret; 
} 
+0

私はあなたの最初の例ではすばらしいですが、第2の方法は目で維持して追跡することが難しい深い機能を奨励しています。 gotoは、プログラムの流れではなく、例外処理のためにstrickly使用されているので、OKです(IMO。) –

+1

@Crazy Chenz:私は実際にその文脈で使用されている「goto」という宗教的な問題はありませんが、私はまだそれを避けています。そのパターンがコード内で共通していれば十分です。 "本当に深い機能"に関するあなたのコメントについては確信していません - 私のリファクタリングは実際には複雑さを減らしていませんか? (例えば、1つ少ない比較、9の代わりに6つの可能なパス)。 – GrahamS

関連する問題