This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [www-patch] bugs.html rewrite,part 5: new section about aliasing problems
- From: Volker Reichelt <reichelt at igpm dot rwth-aachen dot de>
- To: jsm at polyomino dot org dot uk
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 30 Sep 2003 19:01:36 +0200 (CEST)
- Subject: Re: [www-patch] bugs.html rewrite,part 5: new section about aliasing problems
- Reply-to: Volker Reichelt <reichelt at igpm dot rwth-aachen dot de>
On 24 Sep, Joseph S. Myers wrote:
> On Wed, 24 Sep 2003, Volker Reichelt wrote:
>
>> The following patch adds a section about aliasing problems at the
>> beginning of the C non-bugs part of bugs.html.
>
> I think this section should mention that -Wall will now warn for some -
> but not all - cases of this problem.
Good point.
I just added a paragraph
<p>The option <code>-Wstrict-aliasing</code> (which is included in
<code>-Wall</code>) warns about some - but not all - cases of violation
of aliasing rules when <code>-fstrict-aliasing</code> is active.</p>
See below for the complete patch.
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,85 @@ 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>The option <code>-Wstrict-aliasing</code> (which is included in
+<code>-Wall</code>) warns about some - but not all - cases of violation
+of aliasing rules when <code>-fstrict-aliasing</code> is active.</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>
==========================================================================