Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++, is it safe/portable to use static member function pointer for C API callbacks?

In C++, is it safe/portable to use static member function pointer for C API callbacks? Is the ABI of a static member function the same as a C function?

like image 890
Emile Cormier Avatar asked Jan 14 '10 22:01

Emile Cormier


People also ask

Can a callback function be static?

Callbacks need to be static so that they don't have an implicit this parameter as the first argument in their function signature. Show activity on this post. Non-static methods require a 'this' instance, and can only be called upon an object instance.

Why should we not use this pointer with static member function of a class?

For static functions there is no object address at all because static function can be called even before creation of any object using scope resolution operator. Even calling with an object pointer will not associate any "this" pointer to it. Thus this pointer is not available in any static function.

What are the restrictions on the use of static member functions?

You cannot have static and nonstatic member functions with the same names and the same number and type of arguments. Like static data members, you may access a static member function f() of a class A without using an object of class A .

Can we use this pointer with static members?

A static member function can be called, even when a class is not instantiated. A static member function cannot have access to the this pointer of the class.


1 Answers

It is not safe per the C++ standard. As stated in this SO posting:

A C callback function implemented in C++ must be extern "C". It may seem to work as a static function in a class because class-static functions often use the same calling convention as a C function. However, doing that is a bug waiting to happen (see comments below), so please don't - go through an extern "C" wrapper instead.

And according to comments made by Martin York in that answer there are real-world problems trying to do so on some platforms.

Make your C ABI callbacks extern "C".


Edit: Adding some supporting quotes from the standard (emphasis mine):

3.5 "Program and linkage":

After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types specified by all declarations referring to a given object or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound (8.3.4). A violation of this rule on type identity does not require a diagnostic. [3.5/10]

[Note: linkage to non-C++ declarations can be achieved using a linkage-specification (7.5). ] [3.5/11]

And

7.5 "Linkage specifications":

... Two function types with different language linkages are distinct types even if they are otherwise identical. [7.5/1]

So if the code making the callback is using C language bindings for the callback, then the callback target (in the C++ program) must as well.

like image 68
Michael Burr Avatar answered Oct 14 '22 15:10

Michael Burr