I accidentally sent a question to Henri only. Re-adding the list. -j
On Mon, Feb 18, 2019 at 1:24 AM Henri Sivonen <hsivo...@mozilla.com> wrote: > On Fri, Feb 15, 2019 at 6:27 PM Jason Orendorff <jorendo...@mozilla.com> > wrote: > > > > On Fri, Feb 15, 2019 at 3:00 AM Henri Sivonen <hsivo...@mozilla.com> > wrote: > >> > >> If we have no intention of getting rid of -fno-strict-aliasing, it > >> would make sense to document this at > >> > https://developer.mozilla.org/en-US/docs/Mozilla/Using_CXX_in_Mozilla_code > >> and make it explicitly OK for Gecko developers not to worry about > >> type-based alias analysis UB--just like we don't worry about writing > >> exception-safe code. > > > > > > Not worrying about exceptions is easy for me to understand: I can assume > that exceptions are never thrown. > > > > What does it mean to not worry about type-based alias analysis UB? > > (This needs a big "as I understand it" disclaimer from me:) > > It means that it's OK to reinterpret_cast T* into U* even if T and U > differ by more than signedness and neither T nor U is char (or signed > char or unsigned char). > > > What kind of code is OK under -fno-strict-aliasing, > > E.g. code that views a buffer of doubles via uint64_t* (without a > memcpy in between). Or code that casts char16_t* to wchar_t* in clang > on Windows. (MSVC doesn't implement type-based alias analysis anyway.) > > More importantly in terms of usage frequency but less importantly in > terms of what C++ implementations we actually use, viewing a buffer of > uint8_t via a pointer to some other type or vice versa. (Whether > uint8_t is the same as unsigned char and, therefore, whether uint8_t* > can alias anything, or whether uint8_t is a non-char type of the same > size that doesn't inherit char's aliasing rules is > implementation-defined. So whether something is Undefined Behavior is > implementation-defined behavior. AFAIK, in the implementations we > actually use, uint8_t is unsigned char. See > https://bugzilla.mozilla.org/show_bug.cgi?id=1426909#c21 and > https://bugzilla.mozilla.org/show_bug.cgi?id=1426909#c30 .) > > > and what does it do? > > My understanding is that the original purpose is that if you in a loop > read from T* and write on each iteration via U* (where T and U differ > by more than signedness and neither is char), without > -fno-strict-aliasing the compiler doesn't need to pessimize on the > assumption that a write via U* might change the next read via T*. With > -fno-strict-aliasing, the compiler has to pessimize on the assumption > that a write via U* might affect the next read via T*. The problem is > that if accessing a T-typed value via U* is UB *in general*, who knows > what *else* the compiler might do if -fno-strict-aliasing is not used > and there are reinterpret_casts between pointer types, especially with > LTO giving it a broader view to spot UB. > > The unproductivity is being afraid of reinterpret_cast on pointers due > to not knowing what it might let the compiler do and whatever > counter-measures and debates arise from not knowing. With > -fno-strict-aliasing, reinterpret_cast on pointers works in a way that > programmers can reason about. > > As for whether the optimizations enabled by the absence of > -fno-strict-aliasing are valuable: On one hand, MSVC doesn't have the > optimizations to begin with (AFAIK). On the other hand, they perceived > as so valuable that a notable component of the motivation of char8_t > is to make it a separate aliasing domain from char. Similarly, C++ > already makes char16_t and char32_t distinct aliasing domains from > uint16_t and uint32_t while C does not. (So compiling C code that does > not have UB in C++ mode can make the code have UB if > -fno-strict-aliasing is not in use.) > > [...] > > -- > Henri Sivonen > hsivo...@mozilla.com > -j _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform