Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do you need "extern C" for C++ callbacks to C functions?

I find such examples in Boost code.

namespace boost {
   namespace {
     extern "C" void *thread_proxy(void *f)
     {
       ....
     }

   } // anonymous
   void thread::thread_start(...)
   {
       ...
       pthread_create(something,0,&thread_proxy,something_else);
       ...
   }
} // boost

Why do you actually need this extern "C"?

It is clear that the thread_proxy function is private internal and I do not expect that it would be mangled as "thread_proxy" because I actually do not need it mangled at all.

In fact, in all my code that I had written and that runs on many platforms, I never used extern "C" and this had worked as-is with normal functions.

Why is extern "C" added?


My problem is that extern "C" functions pollute the global namespace and they are not actually hidden as the author expects.

This is not a duplicate! I'm not talking about mangling and external linkage. It is obvious in this code that external linkage is unwanted!

Answer: The calling conventions of C and C++ functions are not necessarily the same, so you need to create one with the C calling convention. See 7.5 (p4) of C++ standard.

like image 344
Artyom Avatar asked Apr 07 '10 16:04

Artyom


People also ask

Why is extern C needed?

extern "C" specifies that the function is defined elsewhere and uses the C-language calling convention. The extern "C" modifier may also be applied to multiple function declarations in a block. In a template declaration, extern specifies that the template has already been instantiated elsewhere.

Why do we need callback functions in C?

Callback functions are an essential and often critical concept that developers need to create drivers or custom libraries. A callback function is a reference to executable code that is passed as an argument to other code that allows a lower-level software layer to call a function defined in a higher-level layer(10).

How are callbacks implemented in C?

Callbacks in C are usually implemented using function pointers and an associated data pointer. You pass your function on_event() and data pointers to a framework function watch_events() (for example). When an event happens, your function is called with your data and some event-specific data.

When callback function is called in C?

In simple language, If a reference of a function is passed to another function as an argument to call it, then it will be called as a Callback function. In C, a callback function is a function that is called through a function pointer.


2 Answers

It is clear that the thread_proxy function is private internal and I do not expect that it would be mangled as "thread_proxy" because I actually do not need it mangled at all.

Regardless, it's still going to be mangled. (Had it not been extern "C") That's just how the compiler works. I agree it's conceivable a compiler could say "this doesn't necessarily need to be mangled", but the standard says nothing on it. That said, mangling doesn't come into play here, as we aren't trying to link to the function.

In fact, in all my code that I had written and that runs on many platforms, I never used extern "C" and this had worked as-is with normal functions.

Writing on different platforms has nothing to do with extern "C". I expect all standard C++ code to work on all platforms that have a standard C++ compliant compiler.

extern "C" has to do with interfacing with C, which pthread is a library of. Not only does it not mangle the name, it makes sure it's callable with the C calling convention. It's the calling convention that needs to be guaranteed, and because we can't assume we are running on a certain compiler, platform, or architecture, the best way to try and do that is with the functionality given to us: extern "C".

My problem is that extern "C" functions pollute the global namespace and they are not actually hidden as the author expects.

There's nothing polluting about the above code. It's in an unnamed namespace, and not accessible outside the translation unit.

like image 74
GManNickG Avatar answered Oct 23 '22 18:10

GManNickG


extern "C" linkage does not necessarily mean that only name mangling is suppressed. In fact, there may be a compiler which treats extern "C" as a different calling convention.

The standard leaves this completely open as implementation-defined semantics.

like image 38
greyfade Avatar answered Oct 23 '22 16:10

greyfade