Erro do compilador C2065
'identifier': identificador não declarado
O compilador não consegue localizar a declaração de um identificador. Há muitas causas possíveis para esse erro. As causas mais comuns do erro C2065 o identificador não ter sido declarado, o identificador estar escrito incorretamente, o cabeçalho em que o identificador é declarado não estar incluído no arquivo ou o estar faltando um qualificador de escopo no identificador, por exemplo, cout
em vez de std::cout
. Para obter mais informações sobre declarações em C++, consulte Declarações e definições (C++).
Aqui estão alguns problemas comuns e soluções em mais detalhes.
O identificador não foi declarado
Se o identificador for uma variável ou um nome de função, você precisará declará-lo antes que possa ser usado. Uma declaração da função também precisa incluir os tipos de seus parâmetros antes que a função possa ser usada. Se a variável for declarada usando auto
, o compilador deverá ser capaz de inferir o tipo de seu inicializador.
Se o identificador for membro de uma classe ou struct, ou declarado em um namespace, ele precisará ser qualificado pelo nome da classe ou do struct, ou pelo nome do namespace, quando usado fora do escopo do struct, classe ou namespace. Como alternativa, o namespace precisa ser colocado no escopo por uma diretiva using
, como using namespace std;
, ou o nome do membro precisa ser colocado no escopo por uma declaração using
, como using std::string;
. Caso contrário, o nome não qualificado será considerado um identificador não declarado no escopo atual.
Se o identificador for a marca de um tipo definido pelo usuário, por exemplo, um class
ou struct
, o tipo da marca precisará ser declarado antes que ela possa ser usada. Por exemplo, a declaração struct SomeStruct { /*...*/ };
deve existir antes que você possa declarar uma variável SomeStruct myStruct;
no código.
Se o identificador for um alias de tipo, o tipo deverá ser declarado por uma declaração using
ou typedef
antes que possa ser usado. Por exemplo, você precisa declarar using my_flags = std::ios_base::fmtflags;
para usar my_flags
como um alias de tipo para std::ios_base::fmtflags
.
Exemplo: identificador escrito incorretamente
Esse erro geralmente ocorre quando o nome do identificador está escrito incorretamente ou o identificador usa as letras maiúsculas e minúsculas erradas. O nome na declaração deve corresponder exatamente ao nome usado por você.
// 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;
}
Exemplo: usar um identificador fora do escopo
Esse erro poderá ocorrer se o identificador não tiver o escopo correto. Se você vê o erro C2065 ao usar cout
, um problema de escopo é a causa. Quando as funções e operadores da Biblioteca Padrão de C++ não são totalmente qualificados pelo namespace ou você não trouxe o namespace std
para o escopo atual usando uma diretiva using
, o compilador não consegue encontrá-los. Para corrigir esse problema, você precisa qualificar totalmente os nomes do identificador ou especificar o namespace com a diretiva using
.
A compilação falha neste exemplo porque cout
e endl
são definidos no namespace std
:
// 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;
}
Identificadores declarados dentro dos tipos class
, struct
ou enum class
também devem ser qualificados pelo nome do respectivo escopo delimitador quando você os utiliza fora desse escopo.
Exemplo: o cabeçalho pré-compilado não é o primeiro
Esse erro poderá ocorrer se você colocar diretivas de pré-processador, como #include
, #define
ou #pragma
, antes do #include
de um arquivo de cabeçalho pré-compilado. Se o arquivo de origem usar um arquivo de cabeçalho pré-compilado (ou seja, se ele for compilado usando a opção do compilador /Yu
), todas as diretivas de pré-processador antes do arquivo de cabeçalho pré-compilado serão ignoradas.
A compilação deste exemplo falha porque cout
e endl
são definidos no cabeçalho <iostream>
, que é ignorado porque está incluído antes do arquivo de cabeçalho pré-compilado. Para compilar este exemplo, crie os três arquivos e compile pch.h
(algumas versões do Visual Studio usam stdafx.cpp
) e, em seguida, compile C2065_pch.cpp
.
// pch.h (stdafx.h in Visual Studio 2017 and earlier)
#include <stdio.h>
O arquivo de origem pch.h
ou 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"
Arquivo de origem 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
}
Para corrigir esse problema, adicione o #include de <iostream>
no arquivo de cabeçalho pré-compilado ou mova-o depois que o arquivo de cabeçalho pré-compilado for incluído no arquivo de origem.
Exemplo: arquivo de cabeçalho ausente
O erro poderá ocorrer se você não tiver incluído o arquivo de cabeçalho que declara o identificador. Verifique se o arquivo que contém a declaração do identificador está incluído em todos os arquivos de origem que o usam.
// 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
}
Outra causa possível é se você usa uma lista de inicializadores sem incluir o cabeçalho <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
}
Você poderá ver esse erro nos arquivos de origem do aplicativo da Área de Trabalho do Windows se definir VC_EXTRALEAN
, WIN32_LEAN_AND_MEAN
ou WIN32_EXTRA_LEAN
. Essas macros de pré-processador excluem alguns arquivos de cabeçalho de windows.h
e afxv_w32.h
para acelerar as compilações. Procure em windows.h
e afxv_w32.h
por uma descrição atualizada do que foi excluído.
Exemplo: aspas de fechamento ausentes
Este erro poderá ocorrer se estiver faltando uma aspa de fechamento após uma constante de cadeia de caracteres. É uma maneira fácil de confundir o compilador. A aspa de fechamento ausente pode estar várias linhas antes do local do erro relatado.
// 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
}
Exemplo: usar o iterador fora do escopo do loop for
Esse erro poderá ocorrer se você declarar uma variável de iterador em um loop for
e tentar usar essa variável de iterador fora do escopo do loop for
. O compilador habilita a opção do compilador /Zc:forScope
por padrão. Para obter mais informações, consulte Suporte para o iterador de depuração.
// 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
}
Exemplo: declaração removida pelo pré-processador
Esse erro poderá ocorrer se você se referir a uma função ou variável que estiver em um código compilado condicionalmente que não esteja compilado para sua configuração atual. O erro também poderá ocorrer se você chamar uma função em um arquivo de cabeçalho que atualmente não tem suporte no ambiente de build. Se determinadas variáveis ou funções só estiverem disponíveis quando uma macro de pré-processador específica estiver definida, verifique se o código que chama essas funções só poderá ser compilado quando a mesma macro de pré-processador estiver definida. Esse problema é fácil de detectar no IDE: a declaração da função ficará esmaecida se as macros de pré-processador necessárias não forem definidas para a configuração de build atual.
Aqui está um exemplo de código que funciona quando você compila na Depuração, mas não na Versão:
// 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
}
Exemplo: falha de dedução de tipo de C++/CLI
Esse erro poderá ocorrer ao chamar uma função genérica se o argumento de tipo pretendido não puder ser deduzido com base nos parâmetros usados. Para obter mais informações, consulte Funções genéricas (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
}
Exemplo: parâmetros de atributo de C++/CLI
Esse erro também pode ser gerado como resultado do trabalho de conformidade do compilador que foi feito para o Visual Studio 2005: verificação de parâmetros para atributos do 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;
};