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
, struct
ou 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
, #define
ou #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_MEAN
ou 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;
};