2012-01-03 34 views
2

私は、プログラムが実行されるとき、main()関数が最初に実行されることを知ります。しかし、main()の外側で宣言されたグローバル変数の初期化はいつ行われますか?つまり、次のような変数を宣言すればいいのです。グローバル変数の初期化はいつ行われますか?

unsigned long current_time = millis(); 

void main() { 
    while() { 
     //some code using the current_time global variable 
    } 
} 

ここで、グローバル変数が初期化される正確な時刻は重要です。この文脈で何が起こるか教えてください。

+1

それで、あなたが話している言語を知ることは有益でしょう。 – asawyer

+0

C言語。より具体的には、私はarduinoのプログラミングに傾いています。 –

答えて

2

あなたが話している言語を定義していないので、私はそれをC++と仮定しました。

コンピュータプログラミングでは、グローバル変数は、すべてのスコープでアクセス可能な変数です(シャドウされていない場合)。グローバル変数との相互作用メカニズムは、グローバル環境(グローバル状態も参照)メカニズムと呼ばれます。グローバル環境パラダイムは、すべての変数が共有メモリなしでローカルであるローカル環境パラダイムとは対照的です(したがって、すべての相互作用はメッセージパッシングに再調整できます)。 Wikipedia。原則


、任意の関数の外に定義された変数(つまり、グローバル名前空間であり、そしてクラス静的変数)(メイン前に初期化される)が呼び出されます。翻訳単位内のそのような非ローカル変数は、その宣言順で初期化される(10.4.9節)。そのような変数に明示的な初期化子がない場合、デフォルトでは、その型(10.4.2)のデフォルトに初期化されます。組込み型および列挙型のデフォルトの初期化子値は0です。[...]異なる変換単位でのグローバル変数の初期化順序は保証されていません。したがって、コンパイル単位ごとにグローバル変数の初期化子間に順序依存関係を作成することは賢明ではありません。さらに、グローバル変数の初期化子(14.7)によってスローされた例外をキャッチすることはできません。一般に、グローバル変数の使用を最小限に抑えること、特に、複雑な初期化を必要とするグローバル変数の使用を制限することが最善です。 See

2

(クイック答え:C規格では、初期化のこの種をサポートしていません。あなたは、コンパイラのマニュアルを参照する必要があります)

今、私たちは、言語はCである知っていることを、私たちは何を見ることができます標準はそれについて言わなければなりません。

C99 6.7.8段落4:定数式または文字列リテラルでなければなら静的 記憶域期間を持つオブジェクトの初期化子で

すべての式。

そして新しい2011年の標準(私が持っている少なくとも案)は言う:

静的 記憶域期間を持つオブジェクトの初期化子のすべての式は定数式または文字列リテラルでなければなりません。

静的オブジェクト(たとえば、 current_timeなどのグローバル)を関数呼び出しで初期化することは、制約違反です。コンパイラはそれを拒否することもできますし、警告でそれを受け入れて、言語拡張を提供する場合は何でも好きなことをすることができます。

C標準では、初期化が発生したときはそのような初期化が許可されていないため、このようなことは言いません。基本的には、main()関数が実行を開始する前にコードを実行することはできません。

あなたのコンパイラはこれを拡張機能として許可しています(あなたが実際にこのコードをコンパイルしたと仮定して)。セマンティクスが何であるかを知るには、コンパイラのドキュメントを参照する必要があります。

(通常mainは、多くの場合void main()にはあまりにも多く存在しているの悪い書かれた本からCを学んだプログラマを示しています。int main(void)またはint main(int argc, char *argv[])または同等、またはいくつかの実装定義の方法のように宣言した。しかし、このされますArduinoをターゲットにしているのでおそらくフリースタンディングの実装を使用しているので、main()を宣言する必要がありますが、コンパイラの文章はあなたに教えてくれます)。

関連する問題