1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-01 18:43:33 +02:00

Wrap level dir enumerate callback pointer in struct

In order to let callers provide their OWN callback functions through the
callback function WE provide to PhysFS, we casted the function pointer
to a void pointer.

Unfortunately, this is apparently undefined behavior... if your compiler
doesn't have an extension for it. And most compilers on most
architectures do. (In fact compilers on POSIX systems most certainly
have it due to dlsym() returning a void* which could actually be a
pointer to a function sometimes.)

But imo, it's better to be safe than sorry in this regard. Especially
when given GCC's approach to optimizing int + 100 > int (spoilers: they
remove it entirely! It's faster, but also broken!).

I've decided to wrap it in a struct. And as a nice side effect, if we
ever need more data to be passed through... well we already have this
struct.

Technically, it's also standards-compliant to cast a _pointer to_ a
function pointer to a void pointer. But that extra layer of pointer
indirection would get real confusing to conceptualize real fast (or at
least is more confusing than just putting it in a struct).
This commit is contained in:
Misa 2021-08-19 00:23:51 -07:00
parent 8bade56841
commit 7c18123327

View File

@ -896,12 +896,18 @@ bool FILESYSTEM_loadTiXml2Document(const char *name, tinyxml2::XMLDocument& doc)
return true;
}
struct CallbackWrapper
{
void (*callback)(const char* filename);
};
static PHYSFS_EnumerateCallbackResult enumerateCallback(
void* data,
const char* origdir,
const char* filename
) {
void (*callback)(const char*) = (void (*)(const char*)) data;
struct CallbackWrapper* wrapper = (struct CallbackWrapper*) data;
void (*callback)(const char*) = wrapper->callback;
char builtLocation[MAX_PATH];
SDL_snprintf(
@ -921,8 +927,9 @@ void FILESYSTEM_enumerateLevelDirFileNames(
void (*callback)(const char* filename)
) {
int success;
struct CallbackWrapper wrapper = {callback};
success = PHYSFS_enumerate("levels", enumerateCallback, (void*) callback);
success = PHYSFS_enumerate("levels", enumerateCallback, (void*) &wrapper);
if (success == 0)
{
@ -1200,11 +1207,12 @@ static void levelSaveCallback(const char* filename)
void FILESYSTEM_deleteLevelSaves(void)
{
int success;
struct CallbackWrapper wrapper = {levelSaveCallback};
success = PHYSFS_enumerate(
"saves",
enumerateCallback,
(void*) levelSaveCallback
(void*) &wrapper
);
if (success == 0)