Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to register a non-void function with atexit()?

I'm trying to register a function that returns an int to be called at the end of a program using the atexit() function. (Specifically, the endwin() function from ncurses.)

But since atexit() needs a pointer to a void function, I ran into a problem. I tried the following:

static_cast<void (*)()>(endwin)

but static_casting from an int function to a void function doesn't seem to be allowed.

Is what I'm trying to accomplish possible at all, and if yes, how?

Note: I'm willing to just ignore the return value of the function.


Edit: I also tried creating a lambda function, which seems to do what I want:

atexit([]{ endwin(); });

Is this a good solution compared to a wrapper/forwarding function? (Other than that it needs C++11 and avoids defining a new function whose sole purpose is just forwarding another function.)

like image 540
emlai Avatar asked Feb 14 '15 14:02

emlai


2 Answers

Function pointers can't be converted. Just register a forwarding function:

#ifdef __cplusplus
extern "C"
#endif
void endwin_wrapper() { endwin(); }
...
atexit(endwin_wrapper);

Since you tagged your question C++: if you define the forwarding function in C++ you need to declare it to be extern "C" to have the proper language linkage.

like image 92
Dietmar Kühl Avatar answered Oct 06 '22 16:10

Dietmar Kühl


With the current C++ standard, a lambda is probably the best solution to this:

atexit([]{ endwin(); });

Now there's no need to define a whole new named function with the sole purpose of just forwarding another function.


And if you one day decide you need to have more functions called at program exit, you can either define them with a new call to atexit():

atexit(anotherCleanupFunction);

or, you can just add them to the lambda body:

atexit([]{
  anotherCleanupFunction();
  endwin();
});

However, when you have multiple functions to be registered with atexit(), then a separate wrapper function to hold all those functions may be a better solution. There's no one right answer though, just write good and clear code. (A call to atexit() with by a lambda full of function calls can look rather messy.)

like image 23
emlai Avatar answered Oct 06 '22 18:10

emlai