我有一个只有静态成员的类.
我想在退出时使用"atexit"库函数注册其成员函数之一(下面的代码中的VerifyClean).
在C++常见问题解答说,我必须指定为extern"C"为我要注册这样,就像在下面的例子中的功能.
class Example
{
public:
static void Initialize();
static void DoDirtyStuff {++dirtLevel;}
static void CleanUpStuff {--dirtLevel;}
private:
static void VerifyClean();
// DOESN'T COMPILE: extern "C" static void VerifyClean();
static int dirtLevel;
}
int Example::dirtLevel;
extern "C" void Example::VerifyClean() // DO I NEED extern "C" HERE?
{
assert(dirtLevel == 0);
}
void Example::Initialize()
{
dirtLevel = 0;
atexit(&VerifyClean);
}
Run Code Online (Sandbox Code Playgroud)
我真的必须使用extern"C"吗?
如果我将"atexit"替换为非库函数(在纯C中实现),答案是否会改变?
如果函数VerifyClean是公共的,我决定直接从C++代码调用它,我会得到链接错误或运行时崩溃吗?我问这个是因为声明根本没有提到extern"C",所以常规的C++代码可能会错误地处理函数调用.这在我的MS Visual Studio 2005系统上运行正常.
这是可能的一个编译器使用为C和C++代码不同的调用约定; 然而,在实践中,这几乎从未发生过.
如果你只是想让它工作而不关心支持晦涩的编译器,请不要理会extern "C".在任何广泛使用的编译器中都没有必要.
如果你想要绝对迂腐,或者需要支持一个迂腐的编译器,写一个包装器:
extern "C" static void ExampleVerifyClean()
{
Example::VerifyClean();
}
void Example::Initialize()
{
dirtLevel = 0;
atexit(&ExampleVerifyClean);
}
Run Code Online (Sandbox Code Playgroud)