GNOME Bugzilla – Bug 711153
public structures with padding vs introspection
Last modified: 2018-05-24 15:47:34 UTC
(Filing this bug here since maybe GLib could be part of the solution) Basically https://git.gnome.org/browse/gtk+/commit/?id=d399a4acabf9904118ea4481d057bde39bf0ab0e created a bit of a mess because on Fedora/RHEL we have this "multilib" thing which demands that generated files such as Gtk-3.0.gir be the same across architectures. But now on 32 bit architectures there's an extra field. More generally, it's actually quite hard to correctly consume padding bytes from public structures while preserving ABI across both 32/64 bit. And if you choose to use the C preprocessor like this, it breaks the architecture-independent status of the .gir files, which is something really I'd like to preserve from the perspective of g-i. Specifically for Red Hat Enteprise Linux, we're considering a fix to use transparent unions; see attached. The catch with this is it only works on compilers that support transparent unions. This isn't in C99, only in C11. I don't have at hand accurate information about compiler support. It's been in GNU C for a long time, and from what I can tell MSVC also supports it. The question is whether support is widespread enough to use this upstream in many projects. Failing anonymous unions, other options are: * Use to fixed-size structures that are entirely padding, and have accessor functions; only applies to new API
See gtk+ bug: https://bugzilla.gnome.org/show_bug.cgi?id=711158 Also g-i patch needed: https://bugzilla.gnome.org/show_bug.cgi?id=711157
Hi Colin, I thought it would be better to reply here rather than in the GTK+ bug you mentioned... (In reply to comment #0) > The catch with this is it only works on compilers that support transparent > unions. This isn't in C99, only in C11. I don't have at hand accurate > information about compiler support. It's been in GNU C for a long time, and > from what I can tell MSVC also supports it. It is true that Visual C++ 2008 (and later) supports this syntax, so I can confirm the part about MSVC. With blessings.
(In reply to comment #0) > And if you choose to use the C preprocessor like this, it breaks the > architecture-independent status of the .gir files, which is something really > I'd like to preserve from the perspective of g-i. Is ".gir is arch-independent, only .typelib is arch-dependent" intended to be an invariant? Devil's advocate: would it be so much worse if the .gir for certain "strange" libraries had to go in an arch-dependent directory, e.g. the same one as the typelib? (In reply to comment #0) > More generally, it's actually quite hard to correctly consume padding bytes > from public structures while preserving ABI across both 32/64 bit. Situations that are liable to misfire include: * replacing a pointer with an int or vice versa (breaks on LP64 platforms like x86-64) * replacing a pointer with a long or vice versa (x32 is IP32/L64, 64-bit Windows is LLP64) * replacing an int with a long or vice versa (LP64 again) * having a double anywhere (stricter alignment on many RISC platforms) I think anywhere that does not-completely-obvious padding-byte-consumption deserves to have a G_STATIC_ASSERT(the old size == the new size).
side note: I wonder if we shouldn't add a macro for declaring padding in structures in a safe/portable way, once we identify it, e.g.: struct _FooData { // add 8 pointer-sized padding slots G_POINTER_PADDING (8); // add 4 int-sized padding slots G_INT_PADDING (4); }; this would at least prove to be easier to parse from g-ir-scanner's perspective.
(In reply to comment #3) > (In reply to comment #0) > > And if you choose to use the C preprocessor like this, it breaks the > > architecture-independent status of the .gir files, which is something really > > I'd like to preserve from the perspective of g-i. > > Is ".gir is arch-independent, only .typelib is arch-dependent" intended to be > an invariant? It's not true for GLib-2.0.gir, but I don't think it would be too hard to fix. For everything else on top, if they're using the GLib types and don't have public structures, then they really should be arch-indepenent. > Devil's advocate: would it be so much worse if the .gir for certain "strange" > libraries had to go in an arch-dependent directory, e.g. the same one as the > typelib? It wouldn't be too hard to implement that either. But I feel it'd be a lot nicer if the girs were always arch-independent since we're just so close to that. > * replacing a pointer with an int or vice versa (breaks on LP64 platforms like > x86-64) > * replacing a pointer with a long or vice versa (x32 is IP32/L64, 64-bit > Windows is LLP64) > * replacing an int with a long or vice versa (LP64 again) > * having a double anywhere (stricter alignment on many RISC platforms) > > I think anywhere that does not-completely-obvious padding-byte-consumption > deserves to have a G_STATIC_ASSERT(the old size == the new size). Right, transparent unions take care of all of that. The question in this bug is whether transparent unions are widespread enough to make use of in most of the GNOME stack now.
(In reply to comment #4) > side note: I wonder if we shouldn't add a macro for declaring padding in > structures in a safe/portable way, once we identify it, e.g.: > > struct _FooData { > // add 8 pointer-sized padding slots > G_POINTER_PADDING (8); > > // add 4 int-sized padding slots > G_INT_PADDING (4); > }; > > this would at least prove to be easier to parse from g-ir-scanner's > perspective. Yeah, that would be easier. I'd say the gtk+ issue was greatly exacerbated by the fact there were only 4 guints; padding should always have some pointer elements.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/773.