2017-08-06 7 views
5

変数をif-elseを使用して初期化したいとします。例えば
:Javaではなぜif-else文を使ってconst変数の初期化をサポートしていないのですか?

const int foo; 
if (bar) { 
    foo = 1; 
} else { 
    foo = 2; 
} 

、これは(final代わりにconstを使用して)法的コードです。その理由は、すべての可能な結果において、その変数は一度割り当てられ、決して再割り当てされないからである。 Cでは、これは法的なコードではありません。それはCで法的なコードにすることができない理由は何ですか?

+0

「const」を初期化するのは、定義のポイントで行われ、コンパイラによって実行されるためです。実行時にすべての変数が定義された後、 'if'ステートメントが実行されます。 – Peter

+1

'foo = 1;'は_initialization_ではないことに注意してください。 'foo'に値が与えられたのは初めてですが、_assignment_です。 'int foo = 42;'は_initialization_の例です。 – chux

+0

@jhバック私はそれが不可能である理由を理解しようとしました。私の編集を見てください。 – PSkocik

答えて

6

あなたは三項演算子を使用しますが、静的またはスレッドローカルストレージクラスとオブジェクトに対して、初期化子式はコンパイル時定数である必要がありますことを心に留めておくことができます。

const int bar = 42; 
#define BAR 42 

#if 0 
    const int foo = bar ? 1 : 2; /*ERROR -- bar is not an integer constant */ 
#else 
    const int foo = BAR ? 1 : 2; 
#endif 

void fn(void) 
{ 
    const int foo = bar ? 1 : 2; 
#if 0 
    static const int stc_foo = bar ? 1 : 2; /*ERROR*/ 
#else 
    static const int stc_foo = BAR ? 1 : 2; 
#endif 
} 

理由はif-elseステートメントが初期化に使用できないということです。なぜなら、それを許可するにはC文法にかなりの変更が必要であり、おそらくC文法とセマンティクスをはるかに複雑にするからです。

基本的に、単に宣言子の後に=initializerという式があり、その初期化式が定数であることを確認するのではなく、コンパイラは静的/スレッドローカル変数を覚えておく必要があります初期化し、それに続いて無条件に実行されるコンパイル時に評価可能な分岐を探し、その分岐を初期化に使用します。

さらに、ファイルスコープで文を許可する必要があります(現在のC文法ではファイルスコープでは文が許可されません)。また、翻訳単位ローカルグローバル変数への書き込みに制限されたconstnessとメモリアクセスが検証されます。あるいは、それらは暗黙的にグローバルコンストラクタに変換される可能性がありますが、コンパイルユニット間のコンストラクタの順序付け(コンストラクタの生成が暗黙的であれば解決しにくい)、最初のコンストラクタでグローバルコンストラクタをサポートする実装の必要性静的変数割り当ての現在のやや単純なパフォーマンス特性のぼやけ、

+1

最終的には完全な答えです。私は、静的記憶域を持つcont変数がRODATAセグメントに配置され、多くのシステムでMMUによって保護される(またはuCのフラッシュメモリに配置される)ことを追加します。自動 'const'変数はスタックまたはuPレジスタに格納され、スタックに格納されている場合は意図しない書き込みから保護されません。 –

16

あなたは三項演算子によって条件付きでfoo変数を初期化することができますfooは自動変数でない場合は、初期化の式が評価されるように阿部されなければならない、ということ

const int foo = bar ? 1 : 2;

注意コンパイル時には、コンパイルされません。

+2

ですが、 'foo'が'自動変数 'のときだけです。そうでなければコンパイルエラー –

+5

@PeterJ - そうではありません。 [むしろおもしろい例](http://ideone.com/zj6DuO) – StoryTeller

+0

@StoryTeller - いいえ - この例では割り当ては一定です。コンパイラによって評価されます。非常に悪い例。リンクをクリックしたときにもっと期待される –

3

Cでは、constは、変数を読み取り専用にします。

変数は、宣言時にのみ変数を初期化できます。その後は読み込み専用になります。

そのため、は読み取り専用変数を更新しているので、コードがCでは合法ではありません。

希望しますように!

関連する問題