質問: 宣言と定義の明確な違いはなんですか。 例えば以下の例は、両方定義として考えていいのですか ``` #define a 100 #define b a ```
回答: 「宣言」は、コンパイラに、"この**名前**を使う" と教えるものです。「定義」は、**名前とその中身**を一緒に教えるものです。ですので、「定義」は、そのまま「宣言」ですが、「宣言」だからと言って「定義」とは限りません。 以下、説明のため、定義ではない宣言のことを「ただの宣言」と書くことにします。 ただの宣言は、中身についての情報を持たないので、中身を知らないとできないことをしようとすると、コンパイルエラーまたはリンクエラーになります。 ``` struct my_struct; // ただの宣言 my_struct * p; // OK; ポインタは中身を知らなくても持てる my_struct s; // コンパイルエラー; 中身が分からないと必要なメモリサイズが分からない p->a; // コンパイルエラー; 本当に a がメンバーか不明 ``` 関数の場合 ``` bool f1(int a); // ただの宣言 void f2(int b) { if(f1(b)) { // OK; コンパイル時に中身を知らなくても呼べる // 何かの処理 } } ``` ですが、f1() が他のどこでも定義されていなければ、リンクエラーになります。 ただの宣言と定義の例を少し挙げてみます。 ``` int a; // 定義 extern int b; // ただの宣言 extern int c = 3; // 定義; extern だが初期化されているので struct s1; // ただの宣言 struct s2 { int a; int b; }; // 定義 typedef int my_int; // ただの宣言 int f(int a); // ただの宣言 int f(int a) { return a * a; } // f の再宣言かつ定義 ``` ちなみに `#define` は、他の回答者の皆さんがおっしゃるとおり、宣言でも定義でもありません。コンパイラの本体が、ソースをコンパイルをする前に、プリプロセッサが処理するものだからです。