Delen via


Compilerfout C2065

"id" : niet-declaratiede id

Opmerkingen

De compiler kan de declaratie voor een id niet vinden. Er zijn veel mogelijke oorzaken voor deze fout. De meest voorkomende oorzaken van C2065 zijn dat de id niet is gedeclareerd, dat de id onjuist is gespeld, de header waarin de id wordt gedeclareerd, niet is opgenomen in het bestand of dat de id een bereikscheidingsteken mist, bijvoorbeeld cout in plaats van std::cout. Zie Declaraties en definities (C++) voor meer informatie over declaraties in C++.

Hier volgen enkele veelvoorkomende problemen en oplossingen in meer detail.

De id wordt niet aangegeven

Als de id een variabele of functienaam is, moet u deze declareren voordat deze kan worden gebruikt. Een functiedeclaratie moet ook de typen parameters bevatten voordat de functie kan worden gebruikt. Als de variabele wordt gedeclareerd met behulp autovan, moet de compiler het type kunnen afleiden van de initialisatiefunctie.

Als de id lid is van een klasse of struct of gedeclareerd in een naamruimte, moet deze worden gekwalificeerd door de klasse- of structnaam, of de naamruimtenaam, wanneer deze buiten het bereik van de struct, klasse of naamruimte wordt gebruikt. De naamruimte moet ook binnen het bereik worden gebracht door een using richtlijn, zoals using namespace std;, of de lidnaam moet binnen het bereik worden gebracht door een using verklaring, zoals using std::string;. Anders wordt de niet-gekwalificeerde naam beschouwd als een niet-declaratie-id in het huidige bereik.

Als de id de tag is voor een door de gebruiker gedefinieerd type, bijvoorbeeld a class of struct, moet het type van de tag worden gedeclareerd voordat deze kan worden gebruikt. De declaratie struct SomeStruct { /*...*/ }; moet bijvoorbeeld bestaan voordat u een variabele SomeStruct myStruct; in uw code kunt declareren.

Als de id een typealias is, moet het type worden gedeclareerd door een using declaratie of typedef voordat deze kan worden gebruikt. U moet bijvoorbeeld declareren using my_flags = std::ios_base::fmtflags; voordat u kunt gebruiken my_flags als een typealias voor std::ios_base::fmtflags.

Voorbeeld: verkeerd gespelde id

Deze fout treedt meestal op wanneer de id-naam onjuist is gespeld of de id de verkeerde hoofdletters en kleine letters gebruikt. De naam in de declaratie moet exact overeenkomen met de naam die u gebruikt.

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

Voorbeeld: een niet-gerangschikte id gebruiken

Deze fout kan optreden als uw id niet juist is ingesteld. Als u C2065 ziet wanneer u gebruikt cout, is een bereikprobleem de oorzaak. Wanneer C++ Standard Library-functies en -operators niet volledig zijn gekwalificeerd door naamruimte of als u de std naamruimte niet in het huidige bereik hebt gebracht met behulp van een using instructie, kan de compiler deze niet vinden. Om dit probleem op te lossen, moet u de id-namen volledig kwalificeren of de naamruimte opgeven met de using instructie.

Dit voorbeeld kan niet worden gecompileerd omdat cout en endl zijn gedefinieerd in de std naamruimte:

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

Id's die binnen class, structof enum class typen zijn gedeclareerd, moeten ook worden gekwalificeerd door de naam van het bijbehorende bereik wanneer u ze buiten dat bereik gebruikt.

Voorbeeld: vooraf gecompileerde header is niet eerst

Deze fout kan optreden als u preprocessorrichtlijnen, zoals #include, #defineof #pragma, vóór het #include van een vooraf gecompileerd headerbestand plaatst. Als uw bronbestand gebruikmaakt van een vooraf gecompileerd headerbestand (dat wil gezegd, als het is gecompileerd met behulp van de /Yu compileroptie), worden alle preprocessor-instructies voordat het vooraf gecompileerde headerbestand wordt genegeerd.

Dit voorbeeld kan niet worden gecompileerd omdat cout en endl zijn gedefinieerd in de <iostream> header, die wordt genegeerd omdat deze wordt opgenomen vóór het vooraf gecompileerde headerbestand. Als u dit voorbeeld wilt bouwen, maakt u alle drie de bestanden en compileert pch.h u vervolgens (sommige versies van Visual Studio gebruiken stdafx.cpp) en compileert u C2065_pch.cppdeze.

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

Het pch.h of stdafx.h bronbestand:

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

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

Als u dit probleem wilt oplossen, voegt u de #include toe <iostream> aan het vooraf gecompileerde headerbestand of verplaatst u het nadat het vooraf gecompileerde headerbestand is opgenomen in het bronbestand.

Voorbeeld: ontbrekend headerbestand

De fout kan optreden als u het headerbestand dat de id declareert niet hebt opgenomen. Zorg ervoor dat het bestand met de declaratie voor de id is opgenomen in elk bronbestand dat dit gebruikt.

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

Een andere mogelijke oorzaak is als u een initialisatielijst gebruikt zonder de <initializer_list> header op te geven.

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

Deze fout wordt mogelijk weergegeven in bronbestanden van de Windows-bureaublad-app als u definieert VC_EXTRALEAN, WIN32_LEAN_AND_MEANof WIN32_EXTRA_LEAN. Deze preprocessormacro's sluiten sommige headerbestanden van windows.h en afxv_w32.h naar snelheidscompilaties uit. windows.h Zoek in en afxv_w32.h naar een up-to-datumbeschrijving van wat is uitgesloten.

Voorbeeld: ontbrekende aanhalingstekens sluiten

Deze fout kan optreden als er een aanhalingsteken voor sluiten ontbreekt na een tekenreeksconstante. Het is een eenvoudige manier om de compiler te verwarren. De ontbrekende aanhalingstekens voor sluiten kunnen meerdere regels vóór de gemelde foutlocatie zijn.

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

Voorbeeld: iterator buiten gebruiken voor lusbereik

Deze fout kan optreden als u een iteratorvariabele in een for lus declareert en vervolgens probeert u die iterator-variabele buiten het bereik van de for lus te gebruiken. De compiler schakelt standaard de /Zc:forScope compileroptie in. Zie Debug iterator-ondersteuning voor meer informatie.

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

Voorbeeld: Declaratie van voorverwerker verwijderd

Deze fout kan optreden als u verwijst naar een functie of variabele die zich in voorwaardelijk gecompileerde code bevindt die niet is gecompileerd voor uw huidige configuratie. De fout kan ook optreden als u een functie aanroept in een headerbestand dat momenteel niet wordt ondersteund in uw buildomgeving. Als bepaalde variabelen of functies alleen beschikbaar zijn wanneer een bepaalde preprocessormacro is gedefinieerd, moet u ervoor zorgen dat de code die deze functies aanroept, alleen kan worden gecompileerd wanneer dezelfde preprocessormacro is gedefinieerd. Dit probleem is eenvoudig te herkennen in de IDE: de declaratie voor de functie wordt grijs weergegeven als de vereiste preprocessormacro's niet zijn gedefinieerd voor de huidige buildconfiguratie.

Hier volgt een voorbeeld van code die werkt wanneer u bouwt in Foutopsporing, maar niet bij 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
}

Voorbeeld: C++/CLI-type aftrekfout

Deze fout kan optreden bij het aanroepen van een algemene functie als het beoogde typeargument niet kan worden afgeleid van de gebruikte parameters. Zie Algemene functies (C++/CLI) voor meer informatie.

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

Voorbeeld: C++/CLI-kenmerkparameters

Deze fout kan ook worden gegenereerd als gevolg van het werk van compilercompformance dat is uitgevoerd voor Visual Studio 2005: parametercontrole voor Visual C++-kenmerken.

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