简体   繁体   中英

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_cast ing 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.)

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.

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.)

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

You just write your own wrapper function for endwin() and register that one

void myEndwin() {
    endwin();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM