> Also, in my opinion, violating the strict aliasing rule is a code smell, and 
> so I think we should avoid accommodating bad code with the 
> "-fno-strict-aliasing" flag.

All the major OS kernels (Linux, FreeBSD, and OpenBSD) have strict aliasing 
disabled, and for good reasons. So do a plethora of other C applications and 
libraries.

One, it is insanely easy to accidentally violate the strict aliasing rule when 
manually writing normal C code and there is no way to safely statically 
safeguard against such occurrences. It's an easy source of Heisenbugs with 
basically no performance-related payoff outside of rare circumstances (where 
aliasing can create a performance impact, the pointers usually point to 
entities of the same type).

This also goes for manually written C code that's being included in Nim 
directly, such as static inline functions from header files for external 
functions.

Two, even for generated code (such as code emitted by the Nim compiler), it is 
difficult to avoid undefined behavior in low-level code unless the code 
generator was designed from the ground up for this. There are a number of 
reasons for that:

  1. The gcc developers have held for the longest time that casting through a 
union is _not_ sufficient to work around the pointer aliasing rule and did in 
fact defend that claim fairly agressively (see [this 
thread](http://www.mail-archive.com/[email protected]/msg48627.html), for 
example). I _think_ they've finally gone back on that, because programmers 
expressed a need for that use case, but there are probably still gcc versions 
out there for which this isn't safe; or at least casting through a union 
silences warnings that you'd otherwise get. And I'm not actually 100% sure that 
we're safe now.
  2. For each cast, the union through which to cast would have to be the 
transitive closure of all non-char types that the pointer may ever have pointed 
to, for example:


    
    
    proc main =
      var a: int64 = 1
      var p: ptr float = cast[ptr float](addr a)
      var q: ptr int32 = cast[ptr int32](addr a)
      p[] = 1.0
      q[] = 2'i32
      echo a
    
    main()
    

This example would require a union of int64, int32, and float. Which may be 
impossible to construct if the code is spread over several functions.

> I've even changed -fno-strict-aliasing to "-fstrict-aliasing 
> -Wstrict-aliasing" in build.sh (in csources), and nim compiler compiled 
> without any issues!

"Absence of evidence does not mean evidence of absence", as they say. The 
compiler may just not have triggered the relevant optimizations in this case, 
or you may not have executed the relevant code. You also have no guarantee that 
future versions of gcc/clang won't introduce breakage.

Reply via email to