This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[www-patch] bugs.html rewrite,part 5: new section about aliasing problems
- From: Volker Reichelt <reichelt at igpm dot rwth-aachen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 24 Sep 2003 20:59:35 +0200 (CEST)
- Subject: [www-patch] bugs.html rewrite,part 5: new section about aliasing problems
- Reply-to: Volker Reichelt <reichelt at igpm dot rwth-aachen dot de>
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 <stdio.h>
+
+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 <stdio.h>
+
+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>
==========================================================================