컴파일러 오류 C2065
'identifier': 선언되지 않은 식별자
컴파일러에서 식별자에 대한 선언을 찾을 수 없습니다. 이 오류의 원인에는 여러 가지가 있습니다. C2065의 가장 일반적인 원인은 식별자가 선언되지 않았거나, 식별자의 철자가 틀렸거나, 식별자가 선언된 헤더가 파일에 포함되지 않았거나, 식별자에 범위 한정 cout
std::cout
자가 없다는 것입니다. C++ 의 선언에 대한 자세한 내용은 선언 및 정의(C++)를 참조하세요.
다음은 몇 가지 일반적인 문제 및 해결 방법입니다.
식별자가 선언되지 않았습니다.
식별자가 변수 또는 함수 이름인 경우 이를 사용하려면 먼저 선언해야 합니다. 함수 선언에는 함수를 사용하기 전에 해당 매개 변수 형식도 포함되어야 합니다. 변수를 사용하여 auto
선언된 경우 컴파일러는 이니셜라이저에서 형식을 유추할 수 있어야 합니다.
식별자가 클래스 또는 구조체의 멤버이거나 네임스페이스에 선언된 경우 구조체, 클래스 또는 네임스페이스 범위 외부에서 사용되는 경우 클래스 또는 구조체 이름 또는 네임스페이스 이름으로 정규화되어야 합니다. 또는 네임스페이스를 지시문(예: using
/>)에 의해 범위로 가져와야 합니다. 또는 멤버 이름은 다음과 같은 using std::string;
선언을 통해 using
범위로 가져와야 합니다.using namespace std;
그렇지 않으면 정규화되지 않은 이름은 현재 범위에서 선언되지 않은 식별자로 간주됩니다.
식별자가 사용자 정의 형식의 태그인 경우(예: a class
또는 struct
) 태그 형식을 사용하려면 먼저 태그 형식을 선언해야 합니다. 예를 들어 코드에서 변수 SomeStruct myStruct;
를 선언하려면 먼저 선언 struct SomeStruct { /*...*/ };
이 있어야 합니다.
식별자가 형식 별칭인 경우 형식을 선언하거나 using
typedef
사용하려면 먼저 선언해야 합니다. 예를 들어 에 대한 std::ios_base::fmtflags
형식 별칭으로 사용 my_flags
하려면 먼저 선언 using my_flags = std::ios_base::fmtflags;
해야 합니다.
예: 철자가 틀린 식별자
이 오류는 일반적으로 식별자 이름의 철자가 잘못되었거나 식별자가 잘못된 대문자와 소문자를 사용하는 경우에 발생합니다. 선언의 이름은 사용하는 이름과 정확히 일치해야 합니다.
// 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;
}
예: 범위가 지정되지 않은 식별자 사용
식별자의 범위가 올바르지 않으면 이 오류가 발생할 수 있습니다. 사용할 cout
때 C2065가 표시되면 범위 문제가 원인입니다. C++ 표준 라이브러리 함수 및 연산자가 네임스페이스로 정규화되지 않았거나 지시문을 사용하여 using
네임스페이스를 현재 범위로 가져오 std
지 않은 경우 컴파일러에서 찾을 수 없습니다. 이 문제를 해결하려면 식별자 이름을 정규화하거나 지시문으로 네임스페이 using
스를 지정해야 합니다.
이 예제는 네임스페이스에 정의되어 있으므로 cout
endl
컴파일에 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;
}
또는 형식 내부에 class
struct
enum class
선언된 식별자는 해당 범위 외부에서 사용할 때 바깥쪽 범위의 이름으로 정규화되어야 합니다.
예: 미리 컴파일된 헤더가 첫 번째가 아닙니다.
이 오류는 미리 컴파일된 헤더 파일 앞에 #include
전처리기 지시문(예: #include
, #define
또는#pragma
)을 배치하는 경우에 발생할 수 있습니다. 소스 파일이 미리 컴파일된 헤더 파일(즉, 컴파일러 옵션을 사용하여 컴파일된 경우)을 사용하는 /Yu
경우 미리 컴파일된 헤더 파일 전에 모든 전처리기 지시문이 무시됩니다.
이 예제에서는 미리 컴파일된 헤더 파일 앞에 포함되어 있으므로 무시되는 헤더에 <iostream>
정의되어 있으므로 cout
endl
컴파일에 실패합니다. 이 예제를 빌드하려면 세 개의 파일을 모두 만든 다음 컴파일 pch.h
한 다음(Visual Studio의 일부 버전 사용 stdafx.cpp
) 컴파일합니다 C2065_pch.cpp
.
// pch.h (stdafx.h in Visual Studio 2017 and earlier)
#include <stdio.h>
pch.h
또는 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
:
// 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
}
이 문제를 해결하려면 미리 컴파일된 헤더 파일에 #include <iostream>
추가하거나 미리 컴파일된 헤더 파일이 소스 파일에 포함된 후 이동합니다.
예: 헤더 파일 누락
식별자를 선언하는 헤더 파일을 포함하지 않은 경우 오류가 발생할 수 있습니다. 식별자에 대한 선언이 포함된 파일이 식별자를 사용하는 모든 원본 파일에 포함되어 있는지 확인합니다.
// 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
}
또 다른 가능한 원인은 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
}
정의VC_EXTRALEAN
WIN32_LEAN_AND_MEAN
하거나 WIN32_EXTRA_LEAN
정의한 경우 Windows 데스크톱 앱 원본 파일에서 이 오류가 표시 될 수 있습니다. 이러한 전처리기 매크로는 컴파일 속도를 높이기 위해 일부 헤더 파일을 windows.h
afxv_w32.h
제외합니다. 제외된 windows.h
afxv_w32.h
항목에 대한 최신 설명을 찾아보세요.
예: 닫는 따옴표 누락
문자열 상수 뒤의 닫는 따옴표가 누락된 경우 이 오류가 발생할 수 있습니다. 컴파일러를 혼동하는 쉬운 방법입니다. 누락된 닫는 따옴표는 보고된 오류 위치 이전의 여러 줄일 수 있습니다.
// 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
}
예: 루프 범위 외부에서 반복기 사용
루프에서 for
반복기 변수를 선언한 다음 루프 범위 for
외부에서 해당 반복기 변수를 사용하려고 하면 이 오류가 발생할 수 있습니다. 컴파일러는 기본적으로 컴파일러 옵션을 사용하도록 설정합니다 /Zc:forScope
. 자세한 내용은 디버그 반복기 지원을 참조하세요.
// 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
}
예: 전처리기 제거된 선언
이 오류는 현재 구성에 대해 컴파일되지 않은 조건부로 컴파일된 코드에 있는 함수 또는 변수를 참조하는 경우에 발생할 수 있습니다. 현재 빌드 환경에서 지원되지 않는 헤더 파일에서 함수를 호출하는 경우에도 오류가 발생할 수 있습니다. 특정 전처리기 매크로가 정의된 경우에만 특정 변수 또는 함수를 사용할 수 있는 경우 해당 함수를 호출하는 코드는 동일한 전처리기 매크로가 정의된 경우에만 컴파일할 수 있는지 확인합니다. 이 문제는 IDE에서 쉽게 확인할 수 있습니다. 현재 빌드 구성에 필요한 전처리기 매크로가 정의되지 않은 경우 함수에 대한 선언이 회색으로 표시됩니다.
다음은 디버그에서 빌드할 때 작동하지만 릴리스에서는 작동하지 않는 코드의 예입니다.
// 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
}
예: C++/CLI 유형 추론 실패
이 오류는 사용된 매개 변수에서 의도한 형식 인수를 추론할 수 없는 경우 제네릭 함수를 호출할 때 발생할 수 있습니다. 자세한 내용은 제네릭 함수(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
}
예: C++/CLI 특성 매개 변수
Visual Studio 2005: 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;
};