Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling C++ function pointers from C libraries

Tags:

c++

I have a class that only has static members.

I would like to register one of its member functions (VerifyClean in the code below) to be called at exit, using the "atexit" library function.

The C++ FQA says that i must specify extern "C" for the function i want to register this way, like in the following example.

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

Do i really have to use extern "C"?

Does the answer change if i replace "atexit" with a non-library function (implemented in plain C)?

If the function VerifyClean were public and i decided to call it directly from C++ code, would i get link errors or runtime crashes? I ask this because the declaration doesn't mention extern "C" at all, so regular C++ code might handle the function call incorrectly. This works OK on my MS Visual Studio 2005 system.

like image 466
anatolyg Avatar asked Nov 16 '10 19:11

anatolyg


1 Answers

It is possible for a compiler to use different calling conventions for C and C++ code; however, in practice, this almost never occurs.

If you just want it to work and don't care about supporting obscure compilers, don't bother with extern "C". It's not necessary in any widely-used compiler.

If you want to be absolutely pedantic, or need to support a pedantic compiler, write a wrapper:

extern "C" static void ExampleVerifyClean()
{
  Example::VerifyClean();
}

void Example::Initialize()
{
    dirtLevel = 0;
    atexit(&ExampleVerifyClean);
}
like image 184
John Millikin Avatar answered Sep 22 '22 04:09

John Millikin