Osmose

I make websites and chiptunes!

  • he/him

AKAs:
Lapsed Neurotypical
JavaScript's Strongest Warrior
Fake Podcast Host
Thotleader
Vertically Integrated Boyfriend
Your Fave's Mutual
Certified 5x Severals by the RIAA
Inconsistently Medicated
The Source That Views Back
Carnally Known
The Alternative


Homepage
osmose.ceo/

EDIT: Found a workaround

Presumably unrelated bits removed:

typedef struct {
	void *ctx;
	void (*release)(void *ctx);
} KMIF_SOUND_DEVICE;

typedef struct {
	KMIF_SOUND_DEVICE kmif;
} SNGSOUND;

static void sndrelease(SNGSOUND *sndp)
{
	if (sndp->logtbl) sndp->logtbl->release(sndp->logtbl->ctx);
	XFREE(sndp);
}

KMIF_SOUND_DEVICE *SNGSoundAlloc(Uint32 sng_type)
{
	SNGSOUND *sndp;
	sndp = XMALLOC(sizeof(SNGSOUND));
	if (!sndp) return 0;
    sndp->kmif.ctx = sndp;
	sndp->kmif.release = sndrelease;
}

The error is: error: incompatible function pointer types assigning to 'void (*)(void *)' from 'void (SNGSOUND *)' [-Wincompatible-function-pointer-types] on the sndp->kmif.release = sndrelease; line.

I'm 80% sure this compiled fine on an earlier version of clang, and this got elevated from a warning to an error and I should probably just disable it, but I'm kinda curious why it's failing? My understanding of C++ is that the sndrelease variable should be a pointer to a function, and the SNGSOUND* pointer should be compatible with the void* pointer argument. So why does the compiler think they're incompatible?

(This is a vendored dependency so I can change the code to fix the bug but I'd rather disable the warning if the fix isn't fairly simple.)


You must log in to comment.

in reply to @Osmose's post:

That changes the error to error: incompatible function pointer types assigning to 'void (*)(void *)' from 'void (*)(SNGSOUND *)' [-Wincompatible-function-pointer-types] which implies that it's the void* and SNGSOUND * that are incompatible. Which is useful to know, thanks! But still a head scratcher.

§7.3.14 allows to cast noexcept function pointers to non-noexcept counterparts, §7.6.1.10.6 allows between any two function pointer types with reinterpret_cast but says that the result is Unspecified and that calling the result is Undefined Behaviour™, and §7.6.1.10.8 says that conversions from function pointers to object pointers (which exclude void*) are conditionally supported.

Embrace the UB and GNU C. You have nothing to lose but your chains.