lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Working with and around strict aliasing


From: Vadim Zeitlin
Subject: Re: [lmi] Working with and around strict aliasing
Date: Sun, 20 Sep 2015 00:36:26 +0200

On Sat, 19 Sep 2015 15:46:05 +0000 Greg Chicares <address@hidden> wrote:

GC> First of all, is there only One True Way to do this? Candidates:
GC>  - Classic C cast or the not-much-better reinterpret_cast. That's
GC>    the problem we're trying to solve, so it can't be the solution.
GC>  - The union trick. But at best that relies on implementation-defined
GC>    behavior. Its advantage over reinterpret_cast is that gcc does
GC>    define that behavior; but gcc's just one compiler.

 Hello,

 Actually I'm pretty sure the union trick is safe to use as it's used in
just too much existing code to be broken now, see e.g. this answer from
Pete Becker (who is something I'd trust on anything
C/C++-standard-related): http://stackoverflow.com/a/16637183/15275

 Also, I don't have the C11 standard here, but apparently it enshrined such
use of the unions and even if it didn't make it into C++14, I hope it will
happen sooner or later (and definitely by the time of lmi compiler
upgrade).

 So the use of the union doesn't really seem wrong to me, it's just that
memcpy() works even better in our particular case.

GC>  - Use memcpy(). AIUI, this is guaranteed to work.

 Yes, there is no doubt about this, the only question is whether it works
as efficiently as the cast or union trick because it's definitely not
_guaranteed_ to do it. But apparently in practice it does, at least I
couldn't manage to make any of the compilers I tested (several versions of
g++, clang 3.7 and msvc 14) generate any calls to memcpy() when they could
be avoided.

 In fact, in a rather amusing -- at least if you're not affected by a crash
due to it in your code -- turn of events, it seems that g++ is now so good
at detecting memcpy()-like functions in the code that it automatically
optimizes them to calls to std::memcpy() which are then in turn optimized
away (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56888).

GC> I tried to come up with another name that describes what it does,
GC> rather than how it works. "type_punning_cast" seems like an awful name
GC> because it describes what it does not do. I like "punny_cast", playing
GC> on the usual retort to an awful pun ("That's not punny!", a pun on "funny")
GC> but perhaps that's too precious. What do you think of "convert_cast" or
GC> "type_conversion_cast"?

 I like them better than my initial idea and the other alternatives but
IMHO this is still not ideal and I finally settled on something else:
deserialize_cast(). I think it describes exactly what the function does and
is much more specific than the two latter variants above which seem to
imply that they can convert between arbitrary types and not just convert
from "char*" (BTW, this is why I used "buffer" in my original proposal too,
it was supposed to express the source of the cast). It's not as cute as
punny_cast (which could be appropriately misread as puny_cast as it does so
little), but whether it's a drawback or an advantage is another question.

 I also finally added only a single function because I realized that
deserialize_as_cast() was pretty useless and, actually, I have no idea why
did I propose it in the first place any more, sorry.

 Anyhow, the patches are attached and they were tested with both g++ 5.2
under Linux and 3.4.5 under MSW, as usual.

 Please let me know if you'd like to change/rename anything,
VZ

Attachment: 0001-Avoid-breaking-strict-aliasing-rules-in-MD5-code.patch
Description: Text document

Attachment: 0002-Use-new-deserialize_cast-to-respect-strict-aliasing-.patch
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]