web-dev-qa-db-ja.com

静的関数には、Cのプロトタイプの静的キーワードが必要ですか?

私のCプログラミングブックには、静的関数を作成する場合は、静的キーワードを関数definitionの前に置く必要があると記載されています。プロトタイプについては明示的に何も触れていません。また、例ではプロトタイプを使用せず、静的関数をファイルの先頭に配置しています(そのため、私が想定しているプロトタイプは必要ありません)。

では、静的関数にはプロトタイプの静的キーワードが必要ですか?それともonly定義の前に置くのですか?

45
w1res

いいえ。関数宣言(プロトタイプまたは定義)では、staticを使用した同じ関数の別の宣言の後にある場合、キーワードstaticを省略できます。

関数のstatic宣言が1つある場合、その最初の宣言はstaticでなければなりません。

ISO/IEC 9899:1999、6.7.1で定義されています。

[...]関数のファイルスコープ識別子の宣言にストレージクラス指定子staticが含まれている場合、識別子には内部リンクがあります。

[...]

ストレージクラス指定子externを使用して宣言された識別子で、その識別子の以前の宣言が可視であるスコープで、以前の宣言が内部または外部のリンケージを指定している場合、後の宣言での識別子のリンケージは前の宣言で指定されたリンケージと同じです。

[...]

関数の識別子の宣言にストレージクラス指定子がない場合、そのリンケージは、ストレージクラス指定子externで宣言されたかのように正確に決定されます。

[...]

翻訳単位内で、同じ識別子が内部リンクと外部リンクの両方で表示される場合、動作は未定義です。

したがって、たとえばこれは有効です:

static void foo(void);
void foo(void);
static void foo(void) { }

これも:

static void foo(void) { }
void foo(void);

static void bar(void);
void bar(void) {}

しかし、このコードは間違っています:

void foo(void);
static void foo(void) { }

通常、プロトタイプにもstaticが含まれているはずです(通常、最初に来るため)。

48
undur_gongor