- ベストアンサー
プロトタイプなのにexternを使っても良いのか?
1999年の古いソフトを解析しているのですが、 extern の使い方に疑問が有ります。 ヘッダの中に全ての関数が extern で宣言されています。 その中に自分自身の関数も含まれていますから、プロトタイプ であるべき関数が extern になっています。 しかしエラーにはならない。 これは正当な使い方なのでしょうか。 宜しくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
アセンブラの仕様を頼りにC言語を理解しようとしているところに無理があります。 C言語には、「結合」という概念があり、オブジェクトや関数は、 1. 外部結合 2. 内部結合 3. 無結合 のどれかになります。 このうち、無結合は関数の中で定義された局所オブジェクトに適用されるものですので、関数の場合は外部結合か内部結合のどちらかになります。 extern記憶クラス指定子は外部結合を、static記憶クラス指定子は内部結合を指定するわけですが、ルネサス(というか旧日立系)のアセンブラでいうところのEXTERNやGLOBALのように、参照か定義かを表す概念ではありません。 C言語では定義も宣言の一種なのですが、関数に限っていえば、関数本体があれば定義であり、関数本体がなければ(定義ではない)単なる宣言です。externやstaticが付いていようがいまいが関係ありません。 ちなみに、関数の場合、宣言がなくても参照だけなら可能です。
その他の回答 (1)
- jacta
- ベストアンサー率26% (845/3158)
なぜエラーになると考えたのでしょうか? 関数の場合も宣言の一種ですから、記憶クラス指定子を伴うことはなんら問題ありません。 この辺りの厳密なことを調べたいのであれば、「プログラミング言語C」を読むより、規格書を読むことをお勧めします。
お礼
御回答ありがとう御座います。 >なぜエラーになると考えたのでしょうか? ルネサスH8マイコンのアセンブラでは次のようになっています。 EXP0RT :外部定義シンボルを宣言する IMPORT :外部参照シンボルを宣言する GLOBAL :外部参照シンボルまたは外部定義シンボルを宣言する 外部から自分を参照させるにはEXP0RT、外部を参照するにはIMPORT を使います。方向性が有ります。 ファイルを分割したときに共通ヘッダで IMPORT を宣言すると、 あるファイルにとっては EXP0RT のシンボルが存在します。 それを解決するのが GLOBAL です。 方向性が無いのでシンボルがファイルの内部に有るのか外部 に有るのか明確でないのが欠点です。 C言語の extern は IMPORT 相当だと思ったのですが、GLOBAL 相当だったのですね。
お礼
有り難う御座いました