Search code examples
creturnsdlatexit

Does it matter where in my program I call atexit()?


Basically, I am writing a program in SDL.

This is part of the code:

    // create game window
    game.window = SDL_CreateWindow(
        "Game",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        160,
        144,
        0
    );

    if (game.window == NULL)
    {
        fprintf(stderr, "Window error: %s\n", SDL_GetError());
        return 1;
    }

    atexit(SDL_DestroyWindow());
    atexit(SDL_Quit());
    return 0;
}

My question is the following. Considering the procedural nature of C, what happens if (game.window == NULL) is the case and return 1 executes. Does the program terminate with return 1 without calling the atexit() functions that come after this if-statement?

Does the program still call SDL_DestroyWindow() and SDL_Quit(), which are both in atexit() functions despite the atexit() functions coming after the return 1 in the if (game.window == NULL)-statement?

As far as I understand, C executes code from top to bottom, so how would it know to call the functions in atexit() at the end if return 1 happens before?


Solution

  • First of all, you cannot destroy the window before you know for true you have it created So the call to atexit(3) to register the function to destroy the window must be done after you know the window exists. (this is after the } closing bracket of the if)

    The call to atexit(SDL_Quit); might be done once you have the SDL environment intialized (this is after it has been correctly inited, so it will be called only for a truly intialized environment) but it must be called before the call to register the destroy of the SDL window, as atexit(3) makes the functions you register, to be called in reverse order so it must first desroy the window and then close the SDL environment (and there will be no sense to call a function that destroys a window when the SDL has already been closed).

    By the way, atexit() requires the function pointers, not the result of the function call. Better to write

    atexit(SDL_Quit);
    atexit(SDL_DestroyWindow);
    

    Than what you have written.

    NOTE

    If the functions need parameters, better to write function wrappers to call them with the appropiate parameters.