Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

C Language Dictionary

  1. Home
  2. C Language Dictionary
  3. exit() / atexit() / abort()

exit() / atexit() / abort()

Since: C89(1989)

Functions for terminating a program. There are three types — normal termination, error termination, and forced termination — and you choose the right one depending on the situation.

Syntax

// Terminates the program normally. Runs atexit-registered functions, flushes buffers, and removes temporary files.
// status: pass EXIT_SUCCESS(0) or EXIT_FAILURE(1).
void exit(int status);

// Registers a function to be called when exit() is invoked (at least 32 functions can be registered).
// Registered functions are called in reverse order (LIFO).
// Return value: 0 on success, non-zero on failure.
int atexit(void (*func)(void));

// Terminates the program abnormally. Does not run atexit functions or flush buffers.
// Raises the SIGABRT signal and generates a core dump.
void abort(void);

// Terminates the program immediately. Unlike exit(), performs no cleanup at all.
void _Exit(int status); // C99 and later

Comparison of Termination Functions

FunctionRuns atexitFlushes BuffersUse Case
exit()YesYesStandard normal or error termination.
_Exit()NoNoImmediate exit with no cleanup. Useful for terminating a forked child process.
abort()NoNoAbnormal termination on unrecoverable errors. Also called internally by assert().
return (main)YesYesReturning from main() is equivalent to calling exit(). This is the preferred approach.

Sample Code

sample_exit_atexit_abort.c
#include <stdio.h>
#include <stdlib.h>

// Cleanup functions registered with atexit.
void cleanup_a(void) { printf("cleanup_a: Removed temporary files.\n"); }
void cleanup_b(void) { printf("cleanup_b: Closed the log.\n"); }

int main(void) {
    // Register cleanup functions with atexit (called in reverse order).
    atexit(cleanup_a);
    atexit(cleanup_b); // Called in order: cleanup_b → cleanup_a.

    printf("Starting process.\n");

    // Exit on unrecoverable errors such as a failed file open.
    FILE *fp = fopen("config.txt", "r");
    if (fp == NULL) {
        fprintf(stderr, "Configuration file not found.\n");
        exit(EXIT_FAILURE); // Runs atexit-registered functions before exiting.
    }
    // In this sample, fopen fails and exit() is called.
    fclose(fp);
    return EXIT_SUCCESS;
}

Common Mistakes

Common Mistake: Assuming atexit Handlers Run After abort

Calling abort() does not invoke functions registered with atexit(). If important cleanup is needed, use exit() or return instead.

exit_vs_abort.c
#include <stdio.h>
#include <stdlib.h>

void save_data(void) { printf("save_data: data saved.\n"); }

int main(void) {
    atexit(save_data);

    int error_type = 1;

    if (error_type == 1) {
        /* exit() → save_data is called */
        fprintf(stderr, "Recoverable error. Exiting with exit().\n");
        exit(EXIT_FAILURE);
    } else {
        /* abort() → save_data is NOT called */
        fprintf(stderr, "Unrecoverable error. Aborting.\n");
        abort();
    }
}

Run the following command:

gcc exit_vs_abort.c -o exit_vs_abort
./exit_vs_abort
Recoverable error. Exiting with exit().
save_data: data saved.

Notes

Returning from main() and calling exit(status) are equivalent. Use exit() only when you need to terminate immediately from a deeply nested function; in most cases, returning normally makes the code flow easier to follow.

Functions registered with atexit() are only called when exit() is used. They are not called on abort() or signal-based forced termination. Open files are automatically flushed and closed on exit(), but dynamically allocated memory is not freed — the OS reclaims it when the process ends.

For checking program state, see also assert().

If you find any errors or copyright issues, please .