4

In C++ if I wish to have code called upon something bad happening I can place the code in the destructor, or a try-catch.

Is there a similar technique in C, whereby if the program terminates unexpectedly I can call a particular routine (to clean-up resources)?

user997112
  • 29,025
  • 43
  • 182
  • 361

3 Answers3

7

In C, you use the C standard library function atexit, which allows you to specify a void function taking no parameters to be called when the program terminates (conceptually, when the closing brace } of the first calling of main is reached).

You can register up to 32 such functions in portable C and they are called in the reverse order in which they were registered.

See http://en.cppreference.com/w/c/program/atexit

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
2

If you want to call a specific routine on some specific behavior, you can try to handle signals: sigaction(2)

Here is for example a case, where someone wants to handle a segmentation fault: Segmentation fault handling

A simple example handling CTRL + c:

#include <signal.h>
#include <stdio.h>

void handle_signal(int);

int main(int argc, char* argv[])
{
    //Setup Signal handling
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = handle_signal;
    sigaction(SIGINT, &sa, NULL);
    ...
}

void handle_signal(int signal)
{
    switch (signal) {
        case SIGINT:
            your_cleanup_function();
            break;
        default:
            fprintf(stderr, "Caught wrong signal: %d\n", signal);
            return;
    }
}

As later stated in the comments, there are a bunch of different signal(7) that are available for use.

TacoVox
  • 141
  • 10
  • 1
    I don't feel it answers the question, and you should also mention [signal(7)](http://man7.org/linux/man-pages/man7/signal.7.html) and most importantly **[signal-safety(7)](http://man7.org/linux/man-pages/man7/signal-safety.7.html)** – Basile Starynkevitch Jan 24 '18 at 09:26
  • This answer and the one about `atexit` are complementary: `atexit` fires for normal terminations, signal handlers fire for (most) abnormal terminations. – Sneftel Jan 24 '18 at 09:27
  • With that said, it's a borderline link-only answer. It would be better to include the relevant information directly in the answer. – Sneftel Jan 24 '18 at 09:28
  • 1
    BTW, it also applies to C++, which was mentioned in the question as a solved thing – Basile Starynkevitch Jan 24 '18 at 09:28
  • Thx @BasileStarynkevitch Shoul've mentioned those two as well. – TacoVox Jan 24 '18 at 09:28
  • 2
    `fprintf()` is not async-signal-safe and can not be safely called from within a signal handler. See http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04 – Andrew Henle Jan 24 '18 at 12:00
  • @AndrewHenle did not know this! Good information to have. Thanks! – TacoVox Jan 24 '18 at 13:41
0

No there is no feature like destructors or try-catch blocks in C. You just simply need to check the function return values and clean up resources.

Often C programmers use infamous goto statement to jump to the cleanup code.

void foo()
{
    if (!doA())
        goto exit;
    if (!doB())
        goto cleanupA;
    if (!doC())
        goto cleanupB;

    /* everything has succeeded */
    return;

cleanupB:
    undoB();
cleanupA:
    undoA();
exit:
    return;
}

Example copied from https://stackoverflow.com/a/245761/450989

Grzegorz Żur
  • 47,257
  • 14
  • 109
  • 105
  • What are you saying exactly? This seems to be in contradiction with my answer. – Bathsheba Jan 24 '18 at 09:30
  • 1
    Goto statements are not that infamous! Please check e.g. the [Kernel Coding Style](https://www.kernel.org/doc/html/v4.10/process/coding-style.html#centralized-exiting-of-functions) – TacoVox Jan 24 '18 at 09:44
  • Allthough OP introduces the question by mentioning destructors and try-catch, the actual question is “Is there a similar technique in C, whereby if the program terminates unexpectedly I can call a particular routine (to clean-up resources)?” This answer does not answer the question. – Eric Postpischil Jan 24 '18 at 10:29
  • 3
    @EricPostpischil When OP's write ambiguous or self-contradictory questions, as here, it's pretty hard to answer them! I liked how there were three almost almost completely different answers based on three different interpretations of what the OP might have wanted. Why criticize this answer for "not answering the question"? One could as easily have criticized Bathsheba's answer for not having anything to do with try/catch blocks. – Steve Summit Jan 24 '18 at 11:08
  • @SteveSummit: There is nothing ambiguous or self-contradicting about the OP’s post. The post contains exactly one interrogative sentence, that sentence is clear, it states the OP’s goal of cleaning up upon program termination, and it is consistent with the title. The other sentence merely introduces the question and is not a question. And, even if you figure the OP wanted to know whether C had any sort of local try-catch blocks, it is clear they definitely did want to know about a method to clean up at exit, and this answer does not answer that. – Eric Postpischil Jan 24 '18 at 12:41