Compartir vía


Error del compilador C2065

'identificador': identificador no declarado

El compilador no puede encontrar la declaración de un identificador. Hay muchas causas posibles de este error. Las causas más comunes de C2065 son que el identificador no se ha declarado, que el identificador está mal escrito, que el encabezado donde se declara el identificador no se incluye en el archivo o que falta un calificador de ámbito, por ejemplo, cout en lugar de std::cout. Para más información sobre las declaraciones de C++, vea Declaraciones y definiciones (C++).

A continuación se muestran algunos problemas comunes y soluciones con más detalle.

El identificador no está declarado

Si el identificador es una variable o un nombre de función, debe declararlo antes de que pueda usarse. Una declaración de función también debe incluir los tipos de sus parámetros para que se pueda usar la función. Si la variable se declara mediante auto, el compilador debe ser capaz de inferir el tipo desde su inicializador.

Si el identificador es miembro de una clase o estructura, o se declara en un espacio de nombres, debe calificarse por el nombre de la clase o estructura, o el nombre del espacio de nombres, cuando se usa fuera del ámbito de estructura, clase o espacio de nombres. Como alternativa, el espacio de nombres se debe incluir en el ámbito mediante una directiva using, como using namespace std;, o el nombre del miembro debe incluirse en el ámbito mediante una declaración using, como using std::string;. De lo contrario, el nombre no calificado se considera un identificador no declarado en el ámbito actual.

Si el identificador es la etiqueta de un tipo definido por el usuario, por ejemplo, class o struct, el tipo de la etiqueta debe declararse antes de que pueda usarse. Por ejemplo, la declaración struct SomeStruct { /*...*/ }; debe existir antes de poder declarar una variable SomeStruct myStruct; en el código.

Si el identificador es un alias de tipo, el tipo debe declararse mediante una declaración using o typedef para que pueda usarse. Por ejemplo, debe declarar using my_flags = std::ios_base::fmtflags; para poder usar my_flags como alias de tipo para std::ios_base::fmtflags.

Ejemplo: identificador mal escrito

Este error se suele producir cuando el nombre del identificador está mal escrito o el identificador usa letras mayúsculas y minúsculas de forma incorrecta. El nombre de la declaración debe coincidir exactamente con el nombre que use.

// 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;
}

Ejemplo: uso de un identificador sin ámbito

Este error puede producirse si el ámbito del identificador no es correcto. Si ve C2065 cuando usa cout, la causa es un problema de ámbito. Cuando las funciones y los operadores de la Biblioteca estándar de C++ no están completos por espacio de nombres o no ha llevado el espacio de nombres std al ámbito actual mediante una directiva using, el compilador no puede encontrarlos. Para corregir este problema, debe completar los nombres de identificador o especificar el espacio de nombres con la directiva using.

Este ejemplo no se puede compilar porque cout y endl están definidos en el espacio de nombres 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;
}

Los identificadores que se declaran dentro de los tipos class, struct o enum class también deben calificarse por el nombre de su ámbito de entrada cuando se usan fuera de ese ámbito.

Ejemplo: el encabezado precompilado no es el primero

Este error puede producirse si coloca alguna directiva de preprocesador, como #include, #define o #pragma, antes de la directiva #include de un archivo de encabezado precompilado. Si el archivo de origen usa un archivo de encabezado precompilado (es decir, si se compila mediante la opción del compilador /Yu), se omiten todas las directivas de preprocesador anteriores al archivo de encabezado precompilado.

Este ejemplo no se puede compilar porque cout y endl se definen en el encabezado <iostream>, que se omite porque se incluye antes del archivo de encabezado precompilado. Para compilar este ejemplo, cree los tres archivos y, después, compile pch.h (algunas versiones de Visual Studio usan stdafx.cpp) y, luego, compile C2065_pch.cpp.

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

El archivo de código fuente pch.h 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"

Archivo de origen 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 corregir este problema, agregue la directiva #include de <iostream> al archivo de encabezado precompilado o muévela después de que el archivo de encabezado precompilado se incluya en el archivo de origen.

Ejemplo: falta el archivo de encabezado

El error puede producirse si no se ha incluido el archivo de encabezado que declara el identificador. Asegúrese de que el archivo que contiene la declaración para el identificador se incluye en todos los archivos de código fuente que lo usan.

// 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
}

Otra posible causa es el uso de una lista de inicializadores sin incluir el encabezado <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
}

Es posible que vea este error en los archivos de origen de la aplicación de escritorio de Windows si define VC_EXTRALEAN, WIN32_LEAN_AND_MEAN o WIN32_EXTRA_LEAN. Estas macros de preprocesador excluyen algunos archivos de encabezado de windows.h y afxv_w32.h para acelerar las compilaciones. Busque en windows.h y afxv_w32.h una descripción actualizada de lo que se excluye.

Ejemplo: faltan las comillas de cierre

Este error puede producirse si faltan unas comillas de cierre después de una constante de cadena. Es una forma fácil de confundir al compilador. Las comillas de cierre que faltan pueden ir varias líneas antes de la ubicación de error notificada.

// 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
}

Ejemplo: uso de iterador fuera del ámbito del bucle for

Este error puede producirse si declara una variable de iterador en un bucle for y, después, intenta usar esa variable de iterador fuera del ámbito del bucle for. El compilador habilita la opción del compilador /Zc:forScope de forma predeterminada. Para más información, consulte Compatibilidad de los iteradores de depuración.

// 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
}

Ejemplo: declaración quitada del preprocesador

Este error puede producirse si hace referencia a una función o variable que se encuentra en código compilado condicionalmente que no está compilado para la configuración actual. El error también puede producirse si se llama a una función en un archivo de encabezado que actualmente no se admite en el entorno de compilación. Si determinadas variables o funciones solo están disponibles cuando se define una macro de preprocesador determinada, asegúrese de que el código que llama a esas funciones solo se puede compilar cuando se define la misma macro de preprocesador. Este problema es fácil de detectar en el IDE: la declaración de la función está en gris si no se definen las macros de preprocesador necesarias para la configuración de compilación actual.

A continuación, un ejemplo de código que funciona cuando se compila en Depuración, pero no en Versión:

// 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
}

Ejemplo: error de deducción de tipo C++/CLI

Este error puede producirse al llamar a una función genérica, si el argumento de tipo deseado no se puede deducir de los parámetros usados. Para más información, vea Funciones 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
}

Ejemplo: parámetros de atributo C++/CLI

Este error también puede generarse como resultado del trabajo de conformidad del compilador, efectuado para Visual Studio 2005: comprobación de parámetros de atributos de 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;
};