Errore del compilatore C2065
'identifier': identificatore non dichiarato
Il compilatore non riesce a trovare la dichiarazione per un identificatore. Esistono molte possibili cause per questo errore. Le cause più comuni di C2065 sono che l'identificatore non è stato dichiarato, l'identificatore viene digitato in modo non digitato, l'intestazione in cui viene dichiarato l'identificatore non è incluso nel file o che l'identificatore manca un qualificatore di std::cout
ambito, ad esempio, cout
anziché . Per altre informazioni sulle dichiarazioni in C++, vedere Dichiarazioni e definizioni (C++).
Ecco alcuni problemi comuni e soluzioni in modo più dettagliato.
L'identificatore non è dichiarato
Se l'identificatore è una variabile o un nome di funzione, è necessario dichiararlo prima di poterlo usare. Una dichiarazione di funzione deve includere anche i tipi dei relativi parametri prima che la funzione possa essere usata. Se la variabile viene dichiarata usando auto
, il compilatore deve essere in grado di dedurre il tipo dal relativo inizializzatore.
Se l'identificatore è un membro di una classe o di uno struct o dichiarato in uno spazio dei nomi, deve essere qualificato dal nome della classe o dello struct oppure dal nome dello spazio dei nomi, se usato all'esterno dello struct, della classe o dell'ambito dello spazio dei nomi. In alternativa, lo spazio dei nomi deve essere inserito nell'ambito da una using
direttiva, using namespace std;
ad esempio , o il nome del membro deve essere inserito nell'ambito da una using
dichiarazione, ad esempio using std::string;
. In caso contrario, il nome non qualificato viene considerato un identificatore non dichiarato nell'ambito corrente.
Se l'identificatore è il tag per un tipo definito dall'utente, ad esempio un class
oggetto o struct
, il tipo del tag deve essere dichiarato prima di poterlo usare. Ad esempio, la dichiarazione struct SomeStruct { /*...*/ };
deve esistere prima di poter dichiarare una variabile SomeStruct myStruct;
nel codice.
Se l'identificatore è un alias di tipo, il tipo deve essere dichiarato da una using
dichiarazione o typedef
prima di poterlo usare. Ad esempio, è necessario dichiarare using my_flags = std::ios_base::fmtflags;
prima di poter usare my_flags
come alias di tipo per std::ios_base::fmtflags
.
Esempio: identificatore con errori di ortografia
Questo errore si verifica in genere quando il nome dell'identificatore viene digitato in modo errato o l'identificatore usa lettere maiuscole e minuscole errate. Il nome nella dichiarazione deve corrispondere esattamente al nome usato.
// 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;
}
Esempio: usare un identificatore senza ambito
Questo errore può verificarsi se l'identificatore non ha un ambito corretto. Se viene visualizzato C2065 quando si usa cout
, un problema di ambito è la causa. Quando le funzioni e gli operatori della libreria standard C++ non sono completi per spazio dei nomi o non è stato portato lo std
spazio dei nomi nell'ambito corrente usando una using
direttiva, il compilatore non riesce a trovarli. Per risolvere questo problema, è necessario qualificare completamente i nomi degli identificatori o specificare lo spazio dei nomi con la using
direttiva .
Questo esempio non viene compilato perché cout
e endl
sono definiti nello spazio dei std
nomi :
// 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;
}
Gli identificatori dichiarati all'interno di class
, struct
o devono enum class
essere qualificati anche dal nome del relativo ambito di inclusione quando vengono usati all'esterno di tale ambito.
Esempio: l'intestazione precompilata non è prima
Questo errore può verificarsi se si inseriscono direttive del preprocessore, ad esempio #include
, #define
o #pragma
, prima #include
di un file di intestazione precompilato. Se il file di origine usa un file di intestazione precompilato , ovvero se viene compilato usando l'opzione del /Yu
compilatore, tutte le direttive del preprocessore prima che il file di intestazione precompilato venga ignorato.
Questo esempio non viene compilato perché cout
e endl
sono definiti nell'intestazione <iostream>
, che viene ignorato perché viene incluso prima del file di intestazione precompilato. Per compilare questo esempio, creare tutti e tre i file, quindi compilare pch.h
(alcune versioni di Visual Studio usano stdafx.cpp
), quindi compilare C2065_pch.cpp
.
// pch.h (stdafx.h in Visual Studio 2017 and earlier)
#include <stdio.h>
File pch.h
di origine o stdafx.h
:
// pch.cpp (stdafx.cpp in Visual Studio 2017 and earlier)
// Compile by using: cl /EHsc /W4 /c /Ycstdafx.h stdafx.cpp
#include "pch.h"
C2065_pch.cpp
File di origine :
// 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
}
Per risolvere questo problema, aggiungere il #include di nel file di <iostream>
intestazione precompilato o spostarlo dopo che il file di intestazione precompilato è incluso nel file di origine.
Esempio: file di intestazione mancante
L'errore può verificarsi se non è stato incluso il file di intestazione che dichiara l'identificatore. Assicurarsi che il file che contiene la dichiarazione per l'identificatore sia incluso in ogni file di origine che lo usa.
// 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
}
Un'altra possibile causa è l'uso di un elenco di inizializzatori senza includere l'intestazione <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
}
Questo errore può essere visualizzato nei file di origine dell'app Desktop di Windows se definisci VC_EXTRALEAN
, WIN32_LEAN_AND_MEAN
o WIN32_EXTRA_LEAN
. Queste macro del preprocessore escludono alcuni file di intestazione da windows.h
e afxv_w32.h
per velocizzare le compilazioni. windows.h
Cercare e afxv_w32.h
per una descrizione aggiornata di ciò che è escluso.
Esempio: virgolette di chiusura mancanti
Questo errore può verificarsi se manca una virgoletta di chiusura dopo una costante stringa. È un modo semplice per confondere il compilatore. Le virgolette di chiusura mancanti possono essere diverse righe prima della posizione di errore segnalata.
// 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
}
Esempio: usare l'iteratore all'esterno dell'ambito del ciclo for
Questo errore può verificarsi se si dichiara una variabile iteratore in un for
ciclo e quindi si tenta di usare tale variabile iteratore all'esterno dell'ambito del for
ciclo. Il compilatore abilita l'opzione del /Zc:forScope
compilatore per impostazione predefinita. Per altre informazioni, vedere Supporto dell'iteratore di debug.
// 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
}
Esempio: dichiarazione rimossa del preprocessore
Questo errore può verificarsi se si fa riferimento a una funzione o a una variabile in codice compilato in modo condizionale che non viene compilato per la configurazione corrente. L'errore può verificarsi anche se si chiama una funzione in un file di intestazione attualmente non supportato nell'ambiente di compilazione. Se alcune variabili o funzioni sono disponibili solo quando viene definita una particolare macro del preprocessore, assicurarsi che il codice che chiama tali funzioni possa essere compilato solo quando viene definita la stessa macro del preprocessore. Questo problema è facile da individuare nell'IDE: la dichiarazione per la funzione è disattivata se le macro del preprocessore necessarie non sono definite per la configurazione di compilazione corrente.
Di seguito è riportato un esempio di codice che funziona durante la compilazione in Debug, ma non in Release:
// 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
}
Esempio: Errore di deduzione del tipo C++/CLI
Questo errore può verificarsi quando si chiama una funzione generica, se l'argomento di tipo previsto non può essere dedotto dai parametri usati. Per altre informazioni, vedere Funzioni generice (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
}
Esempio: Parametri dell'attributo C++/CLI
Questo errore può essere generato anche in seguito al lavoro di conformità del compilatore eseguito per Visual Studio 2005: controllo dei parametri per gli attributi di 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;
};