1. ホーム
  2. c

[解決済み】externキーワードがC関数に与える影響について

2022-04-29 02:05:43

質問

C言語において extern キーワードは関数宣言の前に使用されます。 最初、私は extern int f(); を1つのファイルで の場合、そのファイルのスコープ外で実装する必要があります。 しかし、私はその両方があることを知りました。

extern int f();
int f() {return 0;}

そして

extern int f() {return 0;}

は、gccからの警告もなく、うまくコンパイルされます。私は gcc -Wall -ansi を受け付けないのです。 // というコメントがあります。

を使用した場合の効果はありますか? extern 関数定義の前に ? それとも、関数のための副作用のない単なるオプションのキーワードなのでしょうか。

後者の場合、標準設計者はなぜ余計なキーワードを文法に散りばめることにしたのか、理解できません。

EDITです。 はっきりさせるために、私は extern について質問しているのです。 extern 関数 .

解決方法は?

foo.cとbar.cという2つのファイルがあります。

以下は、foo.c です。

#include <stdio.h>

volatile unsigned int stop_now = 0;
extern void bar_function(void);

int main(void)
{
  while (1) {
     bar_function();
     stop_now = 1;
  }
  return 0;
}

さて、以下は bar.c です。

#include <stdio.h>

extern volatile unsigned int stop_now;

void bar_function(void)
{
   if (! stop_now) {
      printf("Hello, world!\n");
      sleep(30);
   }
}

しかし、bar.c はリンク時に foo.c で宣言されたものを必要とし、foo.c はリンク時に bar.c の関数を必要とすることがおわかりいただけるでしょう。

extern'を使うことは、それに続くものがリンク時に(非静的に)見つかることをコンパイラに伝えているのです。この点では、関数も変数も同じように扱われます。

モジュール間でグローバルを共有する必要があり、それをヘッダに入れたり初期化したりしたくない場合に非常に便利です。

技術的には、ライブラリの公開ヘッダ内のすべての関数は「extern」ですが、そのようにラベル付けしても、コンパイラによってはほとんど何のメリットもありません。ほとんどのコンパイラは、自分でそれを理解することができます。ご覧のように、これらの関数は実際には別の場所で定義されているのです。

上記の例では、main() は hello world を一度だけ表示し、続けて bar_function() を入力します。また、bar_function()はこの例では(単なる単純な例なので)返さないことに注意しましょう。もしこれが十分に実用的でないと思われるなら、シグナルが処理されたときに stop_now が変更されることを想像してみてください(それゆえ、volatile)。

エクスターンは、シグナルハンドラや、ヘッダーや構造体に入れたくないミューテックスなどのために非常に便利です。ほとんどのコンパイラは、外部オブジェクトのためにメモリを確保しないように最適化します。なぜなら、オブジェクトが定義されているモジュールでメモリを確保することが分かっているからです。しかし、繰り返しになりますが、最近のコンパイラでは、パブリック関数のプロトタイピング時にそれを指定する意味はほとんどありません。

お役に立てれば幸いです :)