Erreur du compilateur C2065

'identifier' : identificateur non déclaré

Le compilateur ne trouve pas la déclaration d’un identificateur. Il existe de nombreuses causes possibles pour cette erreur. Les causes les plus courantes de C2065 sont que l’identificateur n’a pas été déclaré, que l’identificateur est mal orthographié, l’en-tête où l’identificateur est déclaré n’est pas inclus dans le fichier, ou l’identificateur manque un qualificateur d’étendue, par exemple, cout au lieu de std::cout. Pour plus d’informations sur les déclarations en C++, consultez Déclarations et définitions (C++).

Voici quelques problèmes courants et solutions plus en détail.

L’identificateur n’est pas déclaré

Si l’identificateur est une variable ou un nom de fonction, vous devez le déclarer avant de pouvoir l’utiliser. Une déclaration de fonction doit également inclure les types de ses paramètres avant que la fonction ne puisse être utilisée. Si la variable est déclarée à l’aide auto, le compilateur doit être en mesure de déduire le type de son initialiseur.

Si l’identificateur est membre d’une classe ou d’un struct ou déclaré dans un espace de noms, il doit être qualifié par le nom de classe ou de struct, ou le nom de l’espace de noms, lorsqu’il est utilisé en dehors du struct, de la classe ou de l’étendue de l’espace de noms. Sinon, l’espace de noms doit être placé dans l’étendue par une using directive telle que using namespace std;, ou le nom du membre doit être placé dans l’étendue par une using déclaration, par using std::string;exemple . Sinon, le nom non qualifié est considéré comme un identificateur non déclaré dans l’étendue actuelle.

Si l’identificateur est la balise d’un type défini par l’utilisateur, par exemple, a class ou struct, le type de la balise doit être déclaré avant de pouvoir être utilisé. Par exemple, la déclaration struct SomeStruct { /*...*/ }; doit exister avant de pouvoir déclarer une variable SomeStruct myStruct; dans votre code.

Si l’identificateur est un alias de type, le type doit être déclaré par une using déclaration ou typedef avant de pouvoir être utilisé. Par exemple, vous devez déclarer using my_flags = std::ios_base::fmtflags; avant de pouvoir utiliser my_flags comme alias de type pour std::ios_base::fmtflags.

Exemple : identificateur mal orthographié

Cette erreur se produit généralement lorsque le nom de l’identificateur est mal orthographié, ou que l’identificateur utilise les majuscules et les lettres minuscules incorrectes. Le nom de la déclaration doit correspondre exactement au nom que vous utilisez.

// C2065_spell.cpp
// compile with: cl /EHsc C2065_spell.cpp
#include <iostream>
using namespace std;
int main() {
    int someIdentifier = 42;
    cout << "Some Identifier: " << SomeIdentifier << endl;
    // C2065: 'SomeIdentifier': undeclared identifier
    // To fix, correct the spelling:
    // cout << "Some Identifier: " << someIdentifier << endl;
}

Exemple : utiliser un identificateur non délimité

Cette erreur peut se produire si votre identificateur n’est pas correctement délimité. Si vous voyez C2065 lorsque vous utilisez cout, un problème d’étendue est la cause. Lorsque les fonctions et opérateurs de la bibliothèque standard C++ ne sont pas entièrement qualifiés par espace de noms ou que vous n’avez pas introduit l’espace std de noms dans l’étendue actuelle à l’aide d’une using directive, le compilateur ne peut pas les trouver. Pour résoudre ce problème, vous devez qualifier entièrement les noms d’identificateurs ou spécifier l’espace de noms avec la using directive.

Cet exemple ne parvient pas à compiler, car cout il endl est défini dans l’espace std de noms :

// C2065_scope.cpp
// compile with: cl /EHsc C2065_scope.cpp
#include <iostream>
// using namespace std;   // Uncomment this line to fix

int main() {
    cout << "Hello" << endl;   // C2065 'cout': undeclared identifier
                               // C2065 'endl': undeclared identifier
    // Or try the following line instead
    std::cout << "Hello" << std::endl;
}

Les identificateurs déclarés à l’intérieur de class, structou enum class les types doivent également être qualifiés par le nom de leur étendue englobante lorsque vous les utilisez en dehors de cette étendue.

Exemple : l’en-tête précompilé n’est pas d’abord

Cette erreur peut se produire si vous placez des directives de préprocesseur, telles que #include, #defineou #pragma, avant le #include fichier d’en-tête précompilé. Si votre fichier source utilise un fichier d’en-tête précompilé (autrement dit, s’il est compilé à l’aide de l’option /Yu du compilateur), toutes les directives de préprocesseur avant que le fichier d’en-tête précompilé ne soit ignoré.

Cet exemple ne parvient pas à compiler, car cout il endl est défini dans l’en-tête <iostream> , qui est ignoré car il est inclus avant le fichier d’en-tête précompilé. Pour générer cet exemple, créez les trois fichiers, puis compilez pch.h (certaines versions de Visual Studio utilisent stdafx.cpp), puis compilez C2065_pch.cpp.

// pch.h (stdafx.h in Visual Studio 2017 and earlier)
#include <stdio.h>

Fichier pch.h source ou stdafx.h fichier source :

// pch.cpp (stdafx.cpp in Visual Studio 2017 and earlier)
// Compile by using: cl /EHsc /W4 /c /Ycstdafx.h stdafx.cpp
#include "pch.h"

Fichier source C2065_pch.cpp :

// C2065_pch.cpp
// compile with: cl /EHsc /W4 /Yustdafx.h C2065_pch.cpp
#include <iostream>
#include "stdafx.h"
using namespace std;

int main() {
    cout << "Hello" << endl;   // C2065 'cout': undeclared identifier
                               // C2065 'endl': undeclared identifier
}

Pour résoudre ce problème, ajoutez le #include du <iostream> fichier d’en-tête précompilé ou déplacez-le une fois le fichier d’en-tête précompilé inclus dans votre fichier source.

Exemple : fichier d’en-tête manquant

L’erreur peut se produire si vous n’avez pas inclus le fichier d’en-tête qui déclare l’identificateur. Vérifiez que le fichier qui contient la déclaration de l’identificateur est inclus dans chaque fichier source qui l’utilise.

// C2065_header.cpp
// compile with: cl /EHsc C2065_header.cpp

//#include <stdio.h>
int main() {
    fpos_t file_position = 42; // C2065: 'fpos_t': undeclared identifier
    // To fix, uncomment the #include <stdio.h> line
    // to include the header where fpos_t is defined
}

Une autre cause possible est si vous utilisez une liste d’initialiseurs sans inclure l’en-tête <initializer_list> .

// C2065_initializer.cpp
// compile with: cl /EHsc C2065_initializer.cpp

// #include <initializer_list>
int main() {
    for (auto strList : {"hello", "world"})
        if (strList == "hello") // C2065: 'strList': undeclared identifier
            return 1;
    // To fix, uncomment the #include <initializer_list> line
}

Cette erreur peut s’afficher dans les fichiers sources de l’application De bureau Windows si vous définissez VC_EXTRALEAN, WIN32_LEAN_AND_MEANou WIN32_EXTRA_LEAN. Ces macros de préprocesseur excluent certains fichiers d’en-tête et windows.h afxv_w32.h accélèrent les compilations. windows.h Recherchez et afxv_w32.h recherchez une description à jour de ce qui est exclu.

Exemple : guillemet fermant manquant

Cette erreur peut se produire si vous manquez un guillemet fermant après une constante de chaîne. Il est facile de confondre le compilateur. Le guillemet fermant manquant peut être plusieurs lignes avant l’emplacement d’erreur signalé.

// C2065_quote.cpp
// compile with: cl /EHsc C2065_quote.cpp
#include <iostream>

int main() {
    // Fix this issue by adding the closing quote to "Aaaa"
    char * first = "Aaaa, * last = "Zeee";
    std::cout << "Name: " << first
        << " " << last << std::endl; // C2065: 'last': undeclared identifier
}

Exemple : utiliser un itérateur en dehors de l’étendue de boucle

Cette erreur peut se produire si vous déclarez une variable d’itérateur dans une for boucle, puis essayez d’utiliser cette variable d’itérateur en dehors de l’étendue de la for boucle. Le compilateur active l’option du /Zc:forScope compilateur par défaut. Pour plus d’informations, consultez La prise en charge de l’itérateur de débogage.

// C2065_iter.cpp
// compile with: cl /EHsc C2065_iter.cpp
#include <iostream>
#include <string>

int main() {
    // char last = '!';
    std::string letters{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
    for (const char& c : letters) {
        if ('Q' == c) {
            std::cout << "Found Q!" << std::endl;
        }
        // last = c;
    }
    std::cout << "Last letter was " << c << std::endl; // C2065
    // Fix by using a variable declared in an outer scope.
    // Uncomment the lines that declare and use 'last' for an example.
    // std::cout << "Last letter was " << last << std::endl; // C2065
}

Exemple : déclaration supprimée du préprocesseur

Cette erreur peut se produire si vous faites référence à une fonction ou à une variable qui se trouve dans du code compilé de manière conditionnelle qui n’est pas compilé pour votre configuration actuelle. L’erreur peut également se produire si vous appelez une fonction dans un fichier d’en-tête qui n’est actuellement pas pris en charge dans votre environnement de build. Si certaines variables ou fonctions sont disponibles uniquement lorsqu’une macro de préprocesseur particulière est définie, assurez-vous que le code qui appelle ces fonctions ne peut être compilé que lorsque la même macro de préprocesseur est définie. Ce problème est facile à repérer dans l’IDE : la déclaration de la fonction est grisée si les macros de préprocesseur requises ne sont pas définies pour la configuration de build actuelle.

Voici un exemple de code qui fonctionne lorsque vous générez dans Debug, mais pas Version :

// C2065_defined.cpp
// Compile with: cl /EHsc /W4 /MT C2065_defined.cpp
#include <iostream>
#include <crtdbg.h>
#ifdef _DEBUG
    _CrtMemState oldstate;
#endif
int main() {
    _CrtMemDumpStatistics(&oldstate);
    std::cout << "Total count " << oldstate.lTotalCount; // C2065
    // Fix by guarding references the same way as the declaration:
    // #ifdef _DEBUG
    //    std::cout << "Total count " << oldstate.lTotalCount;
    // #endif
}

Exemple : Échec de déduction de type C++/CLI

Cette erreur peut se produire lors de l’appel d’une fonction générique, si l’argument de type prévu ne peut pas être déduit des paramètres utilisés. Pour plus d’informations, consultez Fonctions génériques (C++/CLI).

// C2065_b.cpp
// compile with: cl /clr C2065_b.cpp
generic <typename ItemType>
void G(int i) {}

int main() {
   // global generic function call
   G<T>(10);     // C2065
   G<int>(10);   // OK - fix with a specific type argument
}

Exemple : paramètres d’attribut C++/CLI

Cette erreur peut également être générée suite au travail de conformité du compilateur effectué pour Visual Studio 2005 : paramètre case activée ing pour les attributs Visual C++.

// C2065_attributes.cpp
// compile with: cl /c /clr C2065_attributes.cpp
[module(DLL, name=MyLibrary)];   // C2065
// try the following line instead
// [module(dll, name="MyLibrary")];

[export]
struct MyStruct {
   int i;
};