2009-06-25 7 views
7

私はCを初めて使っています。サンプルコードを含め、Cの「ファイルの有効範囲」について説明する本が私の目の前にあります。しかし、コードはファイルスコープ付き変数の宣言と初期化のみを行います。たとえば、違法な方法で変数スコープにアクセスしようとすると変数のスコープを検証しません。そう!科学の精神の中で、私は実験を行いました。Cでは、グローバル変数のスコープを宣言されているファイルに限定するにはどうすればよいですか?

ファイルbar.c

static char fileScopedVariable[] = "asdf"; 

ファイルfoo.c

#include <stdio.h> 
#include "bar.c" 

main() 
    { 
    printf("%s\n", fileScopedVariable); 
    } 

私の本によると、Googleに、printf()への呼び出しは失敗しなければならない - しかし、それはしません。 foo.exeは文字列 "asdf"を出力し、正常終了します。私は非常にファイルスコープを使用したいと思います。私は何が欠けていますか?

+4

静的な 'file scoped'で定義された変数を呼び出すことには違いがあります。 #includeされたすべてのファイルに再帰的に貼り付けた結果、1つの翻訳単位に制限されています。 – Eric

答えて

15

bar.cを#includeすると、bar.cの内容をfoo.cにそのままコピーしてからコンパイラが触れる前にプリプロセッサを呼び出すことができます。

インクルードを取り除いて、両方のファイル(たとえばgcc foo.c bar.c)をコンパイルするようコンパイラーに伝え、期待通りにそれを見てください。

編集:私は、主な混乱は、コンパイラとプリプロセッサの間にあると思います。言語規則はコンパイラによって強制されます。プリプロセッサはコンパイラの前で実行され、#がプリフィックスされたコマンドに作用します。すべてのプリプロセッサはプレーンテキストを操作します。コードを解析したり、コードの意味を解釈しようとはしません。 "#include"指示文は非常にリテラルなもので、プリプロセッサに "このファイルの内容をここに挿入する"よう指示します。これは、通常、#hinclude(ヘッダ)ファイルでのみ使用し、関数プロトタイプとextern変数宣言はヘッダファイルに配置するだけです。それ以外の場合は、同じ関数をコンパイルしたり、同じ変数を複数回定義することになります。これは合法ではありません。

+0

ありがとうございました!私はそれを働かせた。 – Metaphile

0

2番目のインクルード命令を削除します。上に述べたように...

コンパイルする前に、コンパイラはそれを前処理します。その段階では、#include、#defineなどの '#'で始まるすべての命令を処理します。

その段階の結果を確認するには、gcc -Eを実行します(gccを使用している場合) 。

6

これは、混乱する用語が原因です。 Cのfile scopeは、1つの翻訳単位にのみ識別子のリンケージを制限することを意味しません。また、スコープが1つの物理ファイルに限定されているわけでもありません。代わりに、file scopeは、あなたの識別子がグローバルであることを意味します。 fileという用語は、すべて#include,#defineおよびその他のプリプロセッサ指令を処理した結果のテキストを示します。

一般に、有効範囲は、1つの翻訳単位内で有効な概念です。複数のコンパイルが含まれている場合、リンケージが開始されます。

ファイルスコープ変数staticを宣言すると、変数internal internal linkageが与えられます。つまり、その変換単位の外側には表示されません。

明示的に静的宣言しない場合、またはファイルスコープ変数externを宣言した場合は、他の翻訳単位にも表示されます。これらは、同じ識別子のファイルスコープ変数を宣言すると、その識別子を同じ変数にリンクします。

foo.cbar.cを含めると、fileScopeVariableの定義がコンパイル中の翻訳単位に挿入されます。したがって、それはそのユニットに表示されます。

2

#あなたがそこにいるように#includeします。言語はそれを許しますが、Cコーダーはそれをしません。そうすれば、人々の混乱を混乱させるでしょう。あなた自身を含む可能性が最も高い

「#include」は、「コンパイラは、他のファイルに移動して、コードのコンパイルを開始する前に、このファイルの先頭に付けてください」という意味です。

vxWorksソースファイルの1つがこれを実行したため、私はかつて完全に混乱しました。私はまだそれ以上のことで彼らにPOedです。

+0

ありがとう、私は今それを得る。 :-) – Metaphile

+0

「PO at them」とは何ですか? – ziyuang

+0

私は未来のヘッダーファイルがどこからでも離れていくと信じています。それらは、Cがヘッダー付きのtypedefとマクロの範囲を制御する手段を持たないためにのみ存在します。 typedefがすでに行っているように、マクロはマクロが宣言されているスコープ内でしか見えないようにする必要があります。ヘッダは、ほとんどのCコードが理解できない理由です。冗長なインクルージョンは、制御の流れに従うことを非常に困難にします。何が何をし、すべてのスコープが無関係なグローバルな定義とtypedefで汚染されています。 – Dmitry