以下ようなコンパイルエラーが稀に発生してしまうことがある。
type value; // Unknown type name 'type'
これは「typeという型が存在しない」という趣旨のエラーメッセージである。
type
に対応する型の定義が見つからないために、このようなエラー発生している。
対処方法
unknown type name '型名' の場合
対応する型が定義されたヘッダファイルを、きちんとインクルードする必要がある。
#include "type.h"
type value; // ok
型名のスペルが間違っている場合にも同様のエラーが発生する原因となる。型名のタイプミスには気を付けよう。
lang v; // Unknown type name 'lang'
long v; // ok
unknown type name 'bool'
bool f(); // error: unknown type name 'bool'
C言語の場合、bool
型はstdbool
ヘッダに定義されているため、#include <stdbool.h>
によるヘッダインクルードが必要となる
#include <stdbool.h>
bool f(); // ok
unknown type name 'friends'
C++のfriendキーワードをfriendsとタイプミスすると当エラーが発生する。
struct X {
friends void f(); // Unknown type name 'friends'
friend void g(); // ok
};
キーワードの記述ミスは本エラーのように、ややこしいエラーメッセージを発生させる原因にもなるため注意したい。
構造体の前方宣言による回避
従来、型名は宣言順に利用しなければならない。
struct A { B* b; }; // Unknown type name 'B'
struct B {};
B
型はA
型の後に定義されているため、B型をA型のメンバとして宣言することはできない。
そのため次のようにBを先に定義するようにする必要がある。
struct B {};
struct A { B* b; };
ただ、どうしてもBの定義をAの後に行いたいような場合には、前方宣言と呼ばれる特殊な宣言方法を用いると良い。
struct B; // 前方宣言
struct A { B* b; }; // ok
struct B {}; // 後から定義
以下のような記述も可能。
struct A { struct B* b; };
struct B {}; // 定義
こうすれば宣言だけを先に行い、実際の定義は後回しにすることができる。前方宣言された型は不完全型となるため、実際の定義が行われるまで変数宣言することはできないが、ポインタ変数としての宣言なら可能となる。
struct B; // 前方宣言
struct B *ptr; // OK
struct B b; // ERROR: Variable has incomplete type 'B'
struct B f(struct B a) { return a; } // ERROR: Variable has incomplete type 'B'