トップページへ

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

小粋空間 » Programming Language » C/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では使えないようです。

« 前の記事へ

次の記事へ »

トップページへ