This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[www-patch] bugs.html rewrite,part 5: new section about aliasing problems


The following patch adds a section about aliasing problems at the
beginning of the C non-bugs part of bugs.html.

Thanks for improvements go to Wolfgang, Giovanni and Janis!

Checked as valid XHMTL.
Ok to commit?

Regards,
Volker


==========================================================================
--- bugs.html	Wed Sep 24 20:36:33 2003
+++ bugs.html	Wed Sep 24 20:44:42 2003
@@ -482,6 +482,81 @@ for more information.</p></dd>
 <h2><a name="nonbugs_c">C</a></h2>
 
 <dl>
+<dt>Casting does not work as expected when optimization is turned on.</dt>
+
+<dd><p>This is often caused by a violation of aliasing rules, which are part
+of the ISO C standard. These rules say that a program is invalid if you try
+to access a variable through a pointer of an incompatible type. This is
+happening in the following example where a short is accessed through a
+pointer to integer (the code assumes 16-bit <code>short</code>s and 32-bit
+<code>int</code>s):</p>
+<blockquote><pre>
+#include &lt;stdio.h&gt;
+
+int main()
+{
+  short a[2];
+
+  a[0]=0x1111;
+  a[1]=0x1111;
+
+  *(int *)a = 0x22222222; /* violation of aliasing rules */
+
+  printf("%x %x\n", a[0], a[1]);
+  return 0;
+}
+</pre></blockquote>
+<p>The aliasing rules were designed to allow compilers more aggressive
+optimization. Basically, a compiler can assume that all changes to variables
+happen through pointers or references to variables of a type compatible to
+the accessed variable. Dereferencing a pointer that violates the aliasing
+rules results in undefined behavior.</p>
+
+<p>In the case above, the compiler may assume that no access through an
+integer pointer can change the array <code>a</code>, consisting of shorts.
+Thus, <code>printf</code> may be called with the original values of
+<code>a[0]</code> and <code>a[1]</code>. What really happens is up to
+the compiler and may change with architecture and optimization level.</p>
+
+<p>Recent versions of GCC turn on the option <code>-fstrict-aliasing</code>
+(which allows alias-based optimizations) by default with <code>-O2</code>.
+And some architectures then really print "1111 1111" as result. Without
+optimization the executable will generate the "expected" output
+"2222 2222".</p>
+
+<p>To disable optimizations based on alias-analysis for faulty legacy code,
+the option <code>-fno-strict-aliasing</code> can be used as a work-around.</p>
+
+<p>To fix the code above, you can use a <code>union</code> instead of a
+cast (note that this is a GCC extension which might not work with other
+compilers):</p>
+<blockquote><pre>
+#include &lt;stdio.h&gt;
+
+int main()
+{
+  union
+  {
+    short a[2];
+    int i;
+  } u;
+
+  u.a[0]=0x1111;
+  u.a[1]=0x1111;
+
+  u.i = 0x22222222;
+
+  printf("%x %x\n", u.a[0], u.a[1]);
+  return 0;
+}
+</pre></blockquote>
+<p>Now the result will always be "2222 2222".</p>
+
+<p>For some more insight into the subject, please have a look at
+<a href="http://mail-index.NetBSD.org/tech-kern/2003/08/11/0001.html";>this
+article</a>.</p></dd>
+
+
 <dt>Cannot use preprocessor directive in macro arguments.</dt>
 <dd><p>Let me guess... you used an older version of GCC to compile code
 that looks something like this:</p>
==========================================================================



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]