Closed smcv closed 1 year ago
More minimal reproducer:
#include <SDL.h>
extern "C" int main (void)
{
SDL_Surface foo;
struct private_hwdata *hwdata;
hwdata = foo.hwdata;
return 0;
}
g++ -ot t.cpp -I .../libsdl1.2/include
(with classic headers) ⇒ works
g++ -ot t.cpp $(pkg-config --cflags --libs sdl)
(with sdl12-compat headers) ⇒ fails
g++ -ot t.cpp -I .../sdl12-compat/include/SDL
(with sdl12-compat headers) ⇒ fails
g++ -ot t.cpp -I .../sdl12-compat/include/SDL
(with the PR I'm about to propose) ⇒ works
I'm in two minds about whether this is a compatibility bug in sdl12-compat, or a bug in the SDLmm C++ binding that's bundled in the asc
package (https://sources.debian.org/src/asc/2.6.1.0-9/source/libs/sdlmm/ which appears to be a copy of https://sourceforge.net/projects/sdlmm/).
If I understand the API correctly, the struct private_hwdata
is exclusively for internal use by SDL, and therefore there's no legitimate reason for third-party code to be looking at that member at all, so it's pointless for SDLmm::BaseSurface to have an accessor for it.
But on the other hand, sdl12-compat is aiming for 100% compatibility with classic SDL 1.2 - does this include misfeatures like this one?
(In sdl2-compat, we likely won't have problems like this, since we could copy the original SDL2 headers over wholesale. In sdl12-compat, we were trying to avoid concerns that the original headers were LGPL-licensed, and the ramifications of that, by writing the most minimal equivalent from scratch.)
To reproduce:
sudo apt build-dep asc
apt source asc
cd asc-*/
dpkg-buildpackage -b
(or compile it in whatever other way you prefer)sudo apt install libsdl1.2-compat-dev
(this replaces "classic SDL 1.2",libsdl1.2-dev
, with sdl12-compat headers)dpkg-buildpackage -b
againExpected result: both calls to
dpkg-buildpackage
succeed.Actual result:
The first build (against classic SDL 1.2) works.
The second build fails:
I think this is because classic SDL 1.2 has
struct private_hwdata *hwdata
as the 8th member ofstruct SDL_Surface
, but sdl12-compat simplifies that tovoid *hwdata
.That simplification is obviously fine from an ABI point of view, because both are data pointers.
From an API point of view, it's a valid simplification in C, because
void *
in C isn't very type-safe: after declaringvoid *generic; SomeType *typed
it's valid to say eithergeneric = typed
ortyped = generic
.But C++ is more type-safe, and will only allow one-way assignment without a cast:
generic = typed
is still OK, buttyped = generic
isn't allowed (and you would have to usetyped = (SomeType *) generic
ortyped = static_cast<SomeType*>(generic)
instead).