web-dev-qa-db-ja.com

「宣言されていない識別子」エラーとは何ですか?どのように修正しますか?

宣言されていない識別子エラーとは何ですか?一般的な原因は何ですか?また、どうすれば修正できますか?

エラーテキストの例:

  • Visual Studioコンパイラーの場合:error C2065: 'cout' : undeclared identifier
  • GCCコンパイラーの場合:'cout' undeclared (first use in this function)
46
sashoalm

それらはほとんどの場合、関数宣言を含むヘッダーファイルをインクルードすることを忘れることに由来します。たとえば、このプログラムは「宣言されていない識別子」エラーを返します。

ヘッダーがありません

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

stdafx.hが上にない(VS固有)

これはVisual Studio固有です。 VSでは、コードの前に#include "stdafx.h"を追加する必要があります。それより前のコードはコンパイラによって無視されるため、これがある場合:

#include <iostream>
#include "stdafx.h"

#include <iostream>は無視されます。以下に移動する必要があります。

#include "stdafx.h"
#include <iostream>

この回答を自由に編集してください。

63
sashoalm

会話で同様の状況を考えてください。友達が「ボブは夕食に来ている」と言って、ボブが誰なのかわからないと想像してください。混乱するでしょう?あなたの友人は、「ボブと呼ばれる同僚がいます。ボブは夕食に来ています」と言っているはずです。これでボブが宣言され、友達が誰のことを話しているかがわかります。

コンパイラーは、何らかの識別子(関数、変数、クラスなどの名前)を使用しようとしましたが、コンパイラーはその宣言を確認していないときに、「未宣言の識別子」エラーを出力します。つまり、コンパイラーは、あなたが何を参照しているかを知らないのです。

CまたはC++でこのようなエラーが発生した場合、使用しようとしているものについてコンパイラーに通知していないことを意味します。宣言は多くの場合ヘッダーファイルに含まれているため、適切なヘッダーが含まれていない可能性があります。もちろん、エンティティを宣言することをまったく覚えていない可能性があります。

一部のコンパイラは、コンテキストに応じてより具体的なエラーを出します。たとえば、タイプXがclangで宣言されていないX x;をコンパイルしようとすると、「不明なタイプ名X」と表示されます。 Xを型として解釈しようとしていることがわかっているため、これははるかに便利です。ただし、yがまだ宣言されていないint x = y;がある場合は、yが正確に何を表すかについて曖昧さがあるため、「未宣言の識別子yの使用」を通知します。

12

名前空間で定義されたカスタムクラスにも同じ問題がありました。名前空間なしでクラスを使用しようとしたため、コンパイラエラー"識別子" MyClass "は未定義"が発生しました。追加中

using namespace <MyNamespace>

またはのようなクラスを使用して

MyNamespace::MyClass myClass;

問題を解決しました。

5

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の宣言が表示されないため、このようなエラーを発行します。 PrintHelloprintHelloは2つの異なる名前で、1つは宣言され、もう1つは宣言されていませんが、メインの本体で使用されています

3

別の可能な状況:テンプレートクラスの親(テンプレートクラス)メンバーにアクセスします。

修正方法:完全な名前で親クラスメンバーを使用します(メンバー名の前にthis->またはparentClassName::を付けます)。

参照: テンプレート:継承クラスでは表示されない親クラスのメンバー変数

1
phil

コンパイラがプロジェクト内でそれを見つけることができないため、cエラーのすべての未宣言変数が発生します。変数が定義されているライブラリの外部(ヘッダー)ファイルを含めることができます。したがって、あなたの質問では、<stdio.h>が必要です。これは、printf()機能を説明する標準入力出力ファイルです。

documentation によると、fprintf()の宣言は、つまり関数を使用する前に含める必要があります。

0
Ishmeet

ほとんどの場合、問題のライブラリをインポートしたことが確実であれば、Visual StudioがIntelliSenseをガイドします。

ここに私のために働いたものがあります:

#include "stdafx.h"が最初に、つまりすべてのインクルードの先頭で宣言されていることを確認してください。

0
Declan Nnadozie

C++識別子は、変数、関数、クラス、モジュール、またはその他のユーザー定義項目を識別するために使用される名前です。 C++では、使用する前にすべての名前を宣言する必要があります。宣言されていないような名前を使用しようとすると、「宣言されていない識別子」コンパイルエラーが発生します。

documentation によると、printf()の宣言はcstdioにあります。つまり、関数を使用する前にそれを含める必要があります。

0
Amit G.

宣言せずに関数を使用するようなものです。ヘッダーファイルにはprintf()関数が含まれます。プログラムにヘッダーファイルを含めます。これがその解決策です。一部のユーザー定義関数は、使用する前に宣言されていない場合でもエラーが発生する場合があります。グローバルに使用する場合、問題はありません。

0
Q_SaD