1

I have the following simple SDL code:

#include <SDL.h>
#include <stdbool.h>
#include <stdio.h>

// helpers

bool init(SDL_Window **win, SDL_Surface **surf) {
        int const width = 800;
        int const height = 600;
        if (SDL_Init(SDL_INIT_VIDEO) != 0) {
                fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
                return false;
        }
        *win = SDL_CreateWindow("Picture test",
                                SDL_WINDOWPOS_CENTERED,
                                SDL_WINDOWPOS_CENTERED,
                                width, height, 0);
        if (*win == NULL) {
                fprintf(stderr,
                        "Unable to create window: %s\n",
                        SDL_GetError());
                return false;
        }
        *surf = SDL_GetWindowSurface(*win);
        return true;
}

bool load_media(SDL_Surface **surf) {
        *surf = SDL_LoadBMP("./sample.bmp");
        if (*surf == NULL) {
                fprintf(stderr, "Unable to load data: %s\n", SDL_GetError());
                return false;
        }
        return true;
}

void close(SDL_Window **win, SDL_Surface **surf) {
        SDL_FreeSurface(*surf);
        SDL_DestroyWindow(*win);
        SDL_Quit();
}


int main()
{
        SDL_Window *win;
        SDL_Surface *surf;
        SDL_Surface *img;
        if (!init(&win, &surf)) {
                return EXIT_FAILURE;
        }
        if (!load_media(&img)) {
                return EXIT_FAILURE;
        }
        SDL_BlitSurface(img, NULL, surf, NULL);
        SDL_UpdateWindowSurface(win);
        SDL_Delay(2000);
        close(&win, &img);
}

My code always segfaults on close (the origin of the segfault according to GDB is the line SDL_FreeSurface(*surf)). More strangely, if I replace the call to close with its definition, this still segfaults in exactly the same place. Specifically, if I replace close(&win, &img) with:

SDL_FreeSurface(img);
SDL_DestroyWindow(win);
SDL_Quit();

the code still segfaults at exactly the same place, even though that function is not even being called. Only if I remove the entire close function does this work correctly. I am completely confused as to what could be causing this.

Koz Ross
  • 3,040
  • 2
  • 24
  • 44
  • You know there is a C library function `int close(int fd);`? Is there any conflict - compiler warnings? – Weather Vane Nov 08 '16 at 21:00
  • @WeatherVane I tried renaming ``close`` to something else, and that fixed it! Surprisingly, despite having every imaginable warning on, the compiler still accepted it! – Koz Ross Nov 08 '16 at 21:18
  • 1
    @KozRoss moreover it may be accepted without any warning, since in glibc `close` (and many others) is a weak symbol. With that kind of simple names (and limited scope) it might be reasonable to use `static` functions. – keltar Nov 09 '16 at 05:39

2 Answers2

5

Please rename your function

void close(SDL_Window **win, SDL_Surface **surf)

since close is a standard C library function.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
2

I can confirm this. Same scenario. Even with -Wall and -Wextra the compiler did not spit out a redeclaration warning. Same for open().

I need an experts' opinion if this is a gcc bug.

  • Solution 1: declare your close() as a static function (e.g. static close()).
  • Solution 2: rename your close() function to something else (e.g. my_close_foo()).
zx485
  • 28,498
  • 28
  • 50
  • 59
markotikvic
  • 131
  • 3
  • 5
  • I *hope* that this is a bug - it'd be pretty scary if GCC didn't at least warn you about something this obviously silly. Same goes for Clang. – Koz Ross Jan 15 '17 at 22:34