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]

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


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 &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>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 &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]