C言語で「静的宣言の後に非静的宣言が続いています」というエラーになる場合の対処

C言語で「静的宣言の後に非静的宣言が続いています」というエラーになる場合の対処

Posted at February 22,2017 12:03 AM
Tag:[C/C++]

C言語で「静的宣言の後に非静的宣言が続いています」というエラーになる場合の対処について紹介します。

1.問題点

下記のサンプルプログラムを作りました。

main.h

#include <stdio.h>
 
void hello_world(void);

main.c

#include <main.h>
 
int main(void) {
    hello_world();
    return 0;
}
static void hello_world(void) {
    printf( "Hello World!\n" );
}

hello.h

#include <stdio.h>
 
extern void hello_world(void);

hello.c

省略

これでmain.cをコンパイルすると、「静的宣言の後に非静的宣言が続いています」というエラーが発生します。

% gcc -I. main.c
main.c:8:13: エラー: 'hello_world' は静的宣言の後に非静的宣言が続いています
 static void hello_world(void) {
             ^
In file included from main.c:1:0:
./main.h:3:6: 備考: 前の 'hello_world' の宣言はここです
 void hello_world(void);
      ^

2.原因

externは、外部ファイルの関数を使うことを宣言したものです。

staticは静的な関数として定義する意味があり、定義されたファイル以外からは参照することができなくなります。

つまり、上記のプログラムは相反する指定をしていることによるエラーとなります。

C言語の仕様を調べていればこのような実装は通常行わないと思いますが。。。

3.対処

"static"を外せば正常にコンパイルできるようになります。

ちなみにg++でコンパイルすると、

% g++ -I.  main.c
main.c: 関数 'void hello_world()' 内:
main.c:8:29: エラー: 'void hello_world()' was declared 'extern' and later 'static' [-fpermissive]
 static void hello_world(void) {
                             ^
In file included from main.c:1:0:
./main.h:3:6: エラー: previous declaration of 'void hello_world()' [-fpermissive]
 void hello_world(void);
      ^

となり、コンパイルで"-fpermissive"を付与する指示が表示されます。

% g++ -I.  -fpermissive main.c
main.c: 関数 'void hello_world()' 内:
main.c:8:29: 警告: 'void hello_world()' was declared 'extern' and later 'static' [-fpermissive]
 static void hello_world(void) {
                             ^
In file included from main.c:1:0:
./main.h:3:6: 警告: previous declaration of 'void hello_world()' [-fpermissive]
 void hello_world(void);
      ^

エラーが警告になります。

-fpermissiveの意味はmanで調べると、

Downgrade some diagnostics about nonconformant code from errors to warnings. Thus, using -fpermissive allows some nonconforming code to compile.(不適合コードに関するいくつかの診断をエラーから警告にダウングレードします。したがって、-fpermissiveを使用すると、いくつかの非適合コードをコンパイルする。)

ということらしいです。

このオプションはg++のみ有効で、gccでは使えないようです。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)