编译器错误 C3861
“identifier”: 找不到标识符
即使使用自变量相关的查找,编译器也无法解析对标识符的引用。
备注
若要修复此错误,请将标识符的使用与标识符声明的大小写和拼写进行比较。 确保范围解析运算符和命名空间 using
指令的用法正确。 如果标识符是在头文件中声明的,请确保在引用该标识符之前已包含该头文件。 如果标识符是在外部可见的,请确保在使用该标识符的任何源文件中声明它。 此外,确保标识符声明或定义未被条件编译指令排除在外。
从 Visual Studio 2015 中的 C 运行时库中移除过时函数的更改可能会导致 C3861。 若要解决此错误,请移除对这些函数的引用,或者替换为其安全替代项(如果有)。 有关详细信息,请参阅过时函数。
如果在从旧版编译器进行项目迁移后出现错误 C3861,则可能遇到与受支持的 Windows 版本相关的问题。 Visual C++ 不再支持面向 Windows 95、Windows 98、Windows ME、Windows NT 或 Windows 2000。 如果你的 WINVER
或 _WIN32_WINNT
宏分配给了这些 Windows 版本中的一个,则必须修改宏。 有关详细信息,请参阅修改 WINVER
和 _WIN32_WINNT
。
示例
未定义标识符
下面的示例将生成 C3861,因为未定义标识符。
// C3861.cpp
void f2(){}
int main() {
f(); // C3861
f2(); // OK
}
标识符不在范围内
下面的示例将生成 C3861,因为标识符仅在其定义的文件范围内可见,除非它已在使用它的其他源文件中声明。
源文件 C3861_a1.cpp
:
// C3861_a1.cpp
// Compile with: cl /EHsc /W4 C3861_a1.cpp C3861_a2.cpp
#include <iostream>
// Uncomment the following line to fix:
// int f(); // declaration makes external function visible
int main() {
std::cout << f() << std::endl; // C3861
}
源文件 C3861_a2.cpp
:
// C3861_a2.cpp
int f() { // declared and defined here
return 42;
}
需要限定命名空间
C++ 标准库中的异常类需要 std
命名空间。
// C3861_b.cpp
// compile with: /EHsc
#include <iostream>
int main() {
try {
throw exception("Exception"); // C3861
// try the following line instead
// throw std::exception("Exception");
}
catch (...) {
std::cout << "caught an exception" << std::endl;
}
}
调用了过时函数
过时函数已从 CRT 库中移除。
// C3861_c.cpp
#include <stdio.h>
int main() {
char line[21]; // room for 20 chars + '\0'
gets( line ); // C3861
// Use gets_s instead.
printf( "The line entered was: %s\n", line );
}
ADL 和友元函数
下面的示例将生成 C3767,因为编译器不能对 FriendFunc
使用自变量相关的查找:
namespace N {
class C {
friend void FriendFunc() {}
friend void AnotherFriendFunc(C* c) {}
};
}
int main() {
using namespace N;
FriendFunc(); // C3861 error
C* pC = new C();
AnotherFriendFunc(pC); // found via argument-dependent lookup
}
若要修复此错误,请在类范围中声明友元并在命名空间范围内定义它:
class MyClass {
int m_private;
friend void func();
};
void func() {
MyClass s;
s.m_private = 0;
}
int main() {
func();
}