Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can a noexcept C++ function be passed as pointer-to-function to an argument for a function with C linkage?

Imagine the following situation where I have a noexcept C++ free function that is passed as function pointer to another function with C linkage:

extern "C" {
   void some_fun(void(*)());
}

void my_fun() noexcept { /* do stuff */; }

int main()
{
   some_fun(my_fun);
}

Is that correct and/or allowed? What happens in this case? What are the semantics here considering that since C++17 noexcept belongs to the type of a function?

In addition, and to my surprise, this even compiles (with both gcc and clang):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

extern "C" {
   void some_fun(void(*)() noexcept);
}

void my_fun() noexcept { /* do stuff */; }

int main()
{
   some_fun(my_fun);
}

Does it even make sense that a function pointer in the signature of a C function allows the qualifier noexcept in it?

>Solution :

Is that correct and/or allowed? What happens in this case? What are the semantics here considering that since C++17 noexcept belongs to the type of a function?

It is correct and allowed. What happens is that there is an implicit conversion sequence from void(*)() noexcept to void(*)() (but not the other way around). This conversion will convert the function pointer to the expected type without noexcept. The function can be called through the pointer without noexcept without any restrictions.

In addition, and to my surprise, this even compiles (with both gcc and clang):

There is no requirement that types used in a function declaration with "C" linkage must be C types. From the point of view of C++ there is no difference to normal behavior, except that the name of the function ignores namespaces and can’t be overloaded (i.e. from the typical implementation point-of-view name mangling is disable).

However, what such a declaration means for actual interop with C code, is implementation-defined. Of course you wouldn’t be able to declare or define the function with the same signature in C. If you changed the signature for the C part of the program, you should really be sure about the specific way in which your compiler compiles the code to make sure that there is well-defined behavior.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading