宣言されていない識別子エラーとは何ですか?一般的な原因は何ですか?また、どうすれば修正できますか?
エラーテキストの例:
error C2065: 'cout' : undeclared identifier
'cout' undeclared (first use in this function)
それらはほとんどの場合、関数宣言を含むヘッダーファイルをインクルードすることを忘れることに由来します。たとえば、このプログラムは「宣言されていない識別子」エラーを返します。
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
修正するには、ヘッダーを含める必要があります。
#include <iostream>
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
ヘッダーを作成して正しくインクルードした場合、ヘッダーに誤った include guard が含まれている可能性があります。
詳細については、 http://msdn.Microsoft.com/en-us/library/aa229215(v = vs.60).aspx を参照してください。
変数のつづりを間違えたときに、初心者のエラーのもう1つの一般的な原因が発生します。
int main() {
int aComplicatedName;
AComplicatedName = 1; /* mind the uppercase A */
return 0;
}
たとえば、std::string
を使用する必要があるため、このコードはエラーになります。
#include <string>
int main() {
std::string s1 = "Hello"; // Correct.
string s2 = "world"; // WRONG - would give error.
}
void f() { g(); }
void g() { }
g
は、最初に使用する前に宣言されていません。修正するには、g
の定義をf
の前に移動します:
void g() { }
void f() { g(); }
または、g
の前にf
の宣言を追加します。
void g(); // declaration
void f() { g(); }
void g() { } // definition
これはVisual Studio固有です。 VSでは、コードの前に#include "stdafx.h"
を追加する必要があります。それより前のコードはコンパイラによって無視されるため、これがある場合:
#include <iostream>
#include "stdafx.h"
#include <iostream>
は無視されます。以下に移動する必要があります。
#include "stdafx.h"
#include <iostream>
この回答を自由に編集してください。
会話で同様の状況を考えてください。友達が「ボブは夕食に来ている」と言って、ボブが誰なのかわからないと想像してください。混乱するでしょう?あなたの友人は、「ボブと呼ばれる同僚がいます。ボブは夕食に来ています」と言っているはずです。これでボブが宣言され、友達が誰のことを話しているかがわかります。
コンパイラーは、何らかの識別子(関数、変数、クラスなどの名前)を使用しようとしましたが、コンパイラーはその宣言を確認していないときに、「未宣言の識別子」エラーを出力します。つまり、コンパイラーは、あなたが何を参照しているかを知らないのです。
CまたはC++でこのようなエラーが発生した場合、使用しようとしているものについてコンパイラーに通知していないことを意味します。宣言は多くの場合ヘッダーファイルに含まれているため、適切なヘッダーが含まれていない可能性があります。もちろん、エンティティを宣言することをまったく覚えていない可能性があります。
一部のコンパイラは、コンテキストに応じてより具体的なエラーを出します。たとえば、タイプX
がclangで宣言されていないX x;
をコンパイルしようとすると、「不明なタイプ名X
」と表示されます。 X
を型として解釈しようとしていることがわかっているため、これははるかに便利です。ただし、y
がまだ宣言されていないint x = y;
がある場合は、y
が正確に何を表すかについて曖昧さがあるため、「未宣言の識別子y
の使用」を通知します。
名前空間で定義されたカスタムクラスにも同じ問題がありました。名前空間なしでクラスを使用しようとしたため、コンパイラエラー"識別子" MyClass "は未定義"が発生しました。追加中
using namespace <MyNamespace>
またはのようなクラスを使用して
MyNamespace::MyClass myClass;
問題を解決しました。
CおよびC++では、使用する前にすべての名前を宣言する必要があります。宣言されていない変数または関数の名前を使用しようとすると、「宣言されていない識別子」エラーが発生します。
ただし、関数は、最初に宣言する必要がないという点で、C(およびCのみ)の特殊なケースです。 Cコンパイラは、関数が呼び出しのように引数の数とタイプで存在すると仮定します。実際の関数定義が一致しない場合、別のエラーが発生します。関数のこの特殊なケースは、C++には存在しません。
これらの種類のエラーを修正するには、関数と変数が使用される前に宣言されるようにします。 printf
の場合、ヘッダーファイル<stdio.h>
(またはC++では<cstdio>
)を含める必要があります。
標準機能については、たとえば この参照サイト 、使用する機能を検索します。各関数のドキュメントには、必要なヘッダーファイルが記載されています。
これらのエラー測定
1.For the Visual Studio compiler: error C2065: 'printf' : undeclared identifier
2.For the GCC compiler: `printf' undeclared (first use in this function)
つまり、名前printf
を使用しますが、コンパイラーは名前が宣言された場所を認識しないため、その意味がわかりません。
プログラムで使用される名前は、使用する前に宣言する必要があります。コンパイラーは、名前が何を示しているかを知る必要があります。
この特定のケースでは、コンパイラは名前printf
の宣言を見ません。私たちが知っているように(しかしコンパイラではありません)、Cのヘッダー<stdio.h>
またはC++のヘッダー<cstdio>
で宣言され、標準(std::
)およびグローバルに配置された標準C関数の名前です(::
)(必ずしもではない)名前空間。
そのため、この関数を使用する前に、対応するヘッダーを含めることにより、名前宣言をコンパイラに提供する必要があります。
たとえば、C:
#include <stdio.h>
int main( void )
{
printf( "Hello World\n" );
}
C++:
#include <cstdio>
int main()
{
std::printf( "Hello World\n" );
// or printf( "Hello World\n" );
// or ::printf( "Hello World\n" );
}
このようなエラーの理由は、単純なタイプミスである場合があります。たとえば、関数PrintHello
を定義したと仮定しましょう
void PrintHello()
{
std::printf( "Hello World\n" );
}
しかし、主にタイプミスをして、PrintHello
の代わりに小文字の 'p'でprintHello
を入力しました。
#include <cstdio>
void PrintHello()
{
std::printf( "Hello World\n" );
}
int main()
{
printHello();
}
この場合、コンパイラは名前printHello
の宣言が表示されないため、このようなエラーを発行します。 PrintHello
とprintHello
は2つの異なる名前で、1つは宣言され、もう1つは宣言されていませんが、メインの本体で使用されています
別の可能な状況:テンプレートクラスの親(テンプレートクラス)メンバーにアクセスします。
修正方法:完全な名前で親クラスメンバーを使用します(メンバー名の前にthis->
またはparentClassName::
を付けます)。
コンパイラがプロジェクト内でそれを見つけることができないため、cエラーのすべての未宣言変数が発生します。変数が定義されているライブラリの外部(ヘッダー)ファイルを含めることができます。したがって、あなたの質問では、<stdio.h>
が必要です。これは、printf()機能を説明する標準入力出力ファイルです。
documentation によると、fprintf()の宣言は、つまり関数を使用する前に含める必要があります。
ほとんどの場合、問題のライブラリをインポートしたことが確実であれば、Visual StudioがIntelliSenseをガイドします。
ここに私のために働いたものがあります:
#include "stdafx.h"
が最初に、つまりすべてのインクルードの先頭で宣言されていることを確認してください。
C++識別子は、変数、関数、クラス、モジュール、またはその他のユーザー定義項目を識別するために使用される名前です。 C++では、使用する前にすべての名前を宣言する必要があります。宣言されていないような名前を使用しようとすると、「宣言されていない識別子」コンパイルエラーが発生します。
documentation によると、printf()の宣言はcstdioにあります。つまり、関数を使用する前にそれを含める必要があります。
宣言せずに関数を使用するようなものです。ヘッダーファイルにはprintf()関数が含まれます。プログラムにヘッダーファイルを含めます。これがその解決策です。一部のユーザー定義関数は、使用する前に宣言されていない場合でもエラーが発生する場合があります。グローバルに使用する場合、問題はありません。