Date: Wed, 19 Apr 2017 12:21:06 +0100
From: Simon McVittie <[hidden email]>
To: [hidden email]
Subject: Re: Strict aliasing, yes or no?
Content-Type: text/plain; charset=us-ascii
On Tue, 18 Apr 2017 at 23:05:04 +0100, Daniel Boles wrote:
> Well, technically, code that relies on aliasing is
> inherently buggy from the outset, because that violates the standard.
Not relying on aliasing forbids casting between dissimilar types, which
rules out "normal" C tricks like casting between GArray and GRealArray
(where GRealArray starts with the same members as GArray) as a way to have
a partially-opaque struct, or an opaque-other-than-size struct on the stack;
so regardless of whether it might be desirable to be writing Standard
C, I'm not sure that GLib can do that without breaking its API.
Hmm, fair point, I wasn't aware of types like that yet.
It is also not particularly clear from ISO/IEC 9899:201x draft N1570 (which
is essentially the same document as Standard C, but without the
price tag) whether the usual C pseudo-object-orientation idiom (which
is a fairly fundamental part of GObject) is considered to be valid in
Standard C. In general, the aliasing rules are not well-understood,
so it is pragmatic to disable aliasing-driven optimizations in code that
is not CPU-bound.
I think this is well-defined: AFAICT, it is specifically allowed to cast between pointers to SomeStruct and SomeOtherStruct whose first member is a SomeStruct.
Put more simply: pointers to structs and pointers to their 1st member are considered to be interchangeable for aliasing purposes - AFAIK.
Most of GNOME is written in pragmatic C (whatever works in gcc and clang
on CPUs that are used in the real world, sometimes with the additional
constraint of also working on MSVC/Windows/x86), not in Standard C. For
instance, standard C doesn't guarantee that 8, 16, 32 and 64-bit types
exist (it only mandates the names like int32_t if such types already
exist!), but GLib requires a type of each of those sizes. Standard C doesn't
guarantee that a pointer with all bits zero is NULL, but GLib libraries
(and probably GLib itself) commonly require that. There are plenty more
examples, many of them things that a typical C programmer is likely to
assume to be always true even though Standard C does not actually
Yeah, I figured there would be things like this. I just wasn't sure whether strict aliasing was such a requirement, or whether we could get by without out. I guess not :)