<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: C Puzzle: Double Trouble</title>
	<atom:link href="http://blog.regehr.org/archives/683/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.regehr.org/archives/683</link>
	<description></description>
	<lastBuildDate>Tue, 21 May 2013 05:57:21 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
	<item>
		<title>By: Jeroen Mostert</title>
		<link>http://blog.regehr.org/archives/683/comment-page-1#comment-3997</link>
		<dc:creator>Jeroen Mostert</dc:creator>
		<pubDate>Sat, 11 Feb 2012 09:24:46 +0000</pubDate>
		<guid isPermaLink="false">http://blog.regehr.org/?p=683#comment-3997</guid>
		<description><![CDATA[The aliasing rules are clearly intended to prohibit this sort of thing, but as far as I can tell, they do not. The union members are distinct objects and they are accessed through pointers of the appropriate type. This situation is obviously allowed by the aliasing rules. Equally obviously, though, the pointers to these objects compare equal, so accessing one is accessing a differently-typed object at the same time, something the aliasing rules are supposed to prevent.

It&#039;s possible to reason this is prevented by the aliasing rules, but this causes inconsistency with the rest of the standard, which explicitly allows type-punning through unions (which should likewise be disallowed under this interpretation, through the same reasoning). The standard would need an explicit change to cover both situations in the intended manner.

I think neither the compilers nor the verifiers are buggy -- it&#039;s the standard that needs a fix. I disagree with Dan that it&#039;s &quot;impossible&quot; to have sound rules (at the very least, every compiler implementation at a particular optimization level, however obtuse, represents one consistent implementation of a set of rules, however complicated), but the fix in this case would be complicated and inelegant -- pointers to union members would need special treatment, likely causing a lot of ugly adjustments to sections that have nothing to do with unions.]]></description>
		<content:encoded><![CDATA[<p>The aliasing rules are clearly intended to prohibit this sort of thing, but as far as I can tell, they do not. The union members are distinct objects and they are accessed through pointers of the appropriate type. This situation is obviously allowed by the aliasing rules. Equally obviously, though, the pointers to these objects compare equal, so accessing one is accessing a differently-typed object at the same time, something the aliasing rules are supposed to prevent.</p>
<p>It&#8217;s possible to reason this is prevented by the aliasing rules, but this causes inconsistency with the rest of the standard, which explicitly allows type-punning through unions (which should likewise be disallowed under this interpretation, through the same reasoning). The standard would need an explicit change to cover both situations in the intended manner.</p>
<p>I think neither the compilers nor the verifiers are buggy &#8212; it&#8217;s the standard that needs a fix. I disagree with Dan that it&#8217;s &#8220;impossible&#8221; to have sound rules (at the very least, every compiler implementation at a particular optimization level, however obtuse, represents one consistent implementation of a set of rules, however complicated), but the fix in this case would be complicated and inelegant &#8212; pointers to union members would need special treatment, likely causing a lot of ugly adjustments to sections that have nothing to do with unions.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: asdf</title>
		<link>http://blog.regehr.org/archives/683/comment-page-1#comment-3995</link>
		<dc:creator>asdf</dc:creator>
		<pubDate>Sat, 11 Feb 2012 02:41:07 +0000</pubDate>
		<guid isPermaLink="false">http://blog.regehr.org/?p=683#comment-3995</guid>
		<description><![CDATA[This is offtopic to this post but there is an elegant way to solve your &quot;Iterating Over The Full Range&quot; problem with the inclusive for loop idiom:

for (bool go = true; go; (go = (f != l)) &amp;&amp; (++f, true)) {
	use(f);
}

// or

do {
	use(f);
} while ((f != l) &amp;&amp; (++f, true)); 

// or my favorite which only works in C++ because stupid C99 doesn&#039;t allow variables to be defined in the if expression

#define inclusive_for(init, cond, inc) \
	if (bool ar3_d0n3_ = false) {} \
	else for (init; !ar3_d0n3_; (ar3_d0n3_ = !(bool)(cond)) &#124;&#124; ((inc), false)) 

inclusive_for (int i = INT_MIN, i != INT_MAX, ++i) {
	use(f);
}]]></description>
		<content:encoded><![CDATA[<p>This is offtopic to this post but there is an elegant way to solve your &#8220;Iterating Over The Full Range&#8221; problem with the inclusive for loop idiom:</p>
<p>for (bool go = true; go; (go = (f != l)) &amp;&amp; (++f, true)) {<br />
	use(f);<br />
}</p>
<p>// or</p>
<p>do {<br />
	use(f);<br />
} while ((f != l) &amp;&amp; (++f, true)); </p>
<p>// or my favorite which only works in C++ because stupid C99 doesn&#8217;t allow variables to be defined in the if expression</p>
<p>#define inclusive_for(init, cond, inc) \<br />
	if (bool ar3_d0n3_ = false) {} \<br />
	else for (init; !ar3_d0n3_; (ar3_d0n3_ = !(bool)(cond)) || ((inc), false)) </p>
<p>inclusive_for (int i = INT_MIN, i != INT_MAX, ++i) {<br />
	use(f);<br />
}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ryan Fox</title>
		<link>http://blog.regehr.org/archives/683/comment-page-1#comment-3983</link>
		<dc:creator>Ryan Fox</dc:creator>
		<pubDate>Thu, 09 Feb 2012 19:15:05 +0000</pubDate>
		<guid isPermaLink="false">http://blog.regehr.org/?p=683#comment-3983</guid>
		<description><![CDATA[From the GCC manual: &quot;Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type. ...  access by taking the address, casting the resulting pointer and dereferencing the result has undefined behavior, even if the cast uses a union type.&quot;

Also, -fstrict-aliasing is enabled for -O2 but not -O1. I imagine that if you used -fstrict-aliasing without a -O flag, you&#039;d have the same problem.]]></description>
		<content:encoded><![CDATA[<p>From the GCC manual: &#8220;Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type. &#8230;  access by taking the address, casting the resulting pointer and dereferencing the result has undefined behavior, even if the cast uses a union type.&#8221;</p>
<p>Also, -fstrict-aliasing is enabled for -O2 but not -O1. I imagine that if you used -fstrict-aliasing without a -O flag, you&#8217;d have the same problem.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dan Gohman</title>
		<link>http://blog.regehr.org/archives/683/comment-page-1#comment-3982</link>
		<dc:creator>Dan Gohman</dc:creator>
		<pubDate>Thu, 09 Feb 2012 19:10:00 +0000</pubDate>
		<guid isPermaLink="false">http://blog.regehr.org/?p=683#comment-3982</guid>
		<description><![CDATA[In your example, the code happens to read from a member of a union which is not the most recently written one.  However, it is possible to write similar code which does not have this problem, yet which still exhibits problematic behavior.  See the examples in this Defect Report:

http://open-std.org/JTC1/SC22/WG14/www/docs/dr_236.htm

This report is categorized as Closed, however the explanation in the Committee Response is based on reasoning which isn&#039;t obviously supported by the standard.

In general, there does not appear to be any way to have sound type-based aliasing rules in a language that also has non-discriminated unions, untyped (e.g. malloc) memory, and pointers.  However, type-based alias rules are considered an important feature, and the committee has chosen to keep it anyway.  Consequently, the standard is inconsistent.  In practice, each compiler is left to choose for itself the extent to which it is willing to trade safety for optimization.]]></description>
		<content:encoded><![CDATA[<p>In your example, the code happens to read from a member of a union which is not the most recently written one.  However, it is possible to write similar code which does not have this problem, yet which still exhibits problematic behavior.  See the examples in this Defect Report:</p>
<p><a href="http://open-std.org/JTC1/SC22/WG14/www/docs/dr_236.htm" rel="nofollow">http://open-std.org/JTC1/SC22/WG14/www/docs/dr_236.htm</a></p>
<p>This report is categorized as Closed, however the explanation in the Committee Response is based on reasoning which isn&#8217;t obviously supported by the standard.</p>
<p>In general, there does not appear to be any way to have sound type-based aliasing rules in a language that also has non-discriminated unions, untyped (e.g. malloc) memory, and pointers.  However, type-based alias rules are considered an important feature, and the committee has chosen to keep it anyway.  Consequently, the standard is inconsistent.  In practice, each compiler is left to choose for itself the extent to which it is willing to trade safety for optimization.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Pascal Cuoq</title>
		<link>http://blog.regehr.org/archives/683/comment-page-1#comment-3981</link>
		<dc:creator>Pascal Cuoq</dc:creator>
		<pubDate>Thu, 09 Feb 2012 18:48:56 +0000</pubDate>
		<guid isPermaLink="false">http://blog.regehr.org/?p=683#comment-3981</guid>
		<description><![CDATA[Speaking of GCC&#039;s documentation, the last example in this section looks a bit like like John&#039;s program, and it is given as an example what not to do:

http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Optimize-Options.html#index-fstrict_002daliasing-542

          int f() {
            a_union t;
            int* ip;
            t.d = 3.0;
            ip = &amp;t.i;
            return *ip;
          }

The difference is that John&#039;s program reads through the union with  fn2 (b.f0);]]></description>
		<content:encoded><![CDATA[<p>Speaking of GCC&#8217;s documentation, the last example in this section looks a bit like like John&#8217;s program, and it is given as an example what not to do:</p>
<p><a href="http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Optimize-Options.html#index-fstrict_002daliasing-542" rel="nofollow">http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Optimize-Options.html#index-fstrict_002daliasing-542</a></p>
<p>          int f() {<br />
            a_union t;<br />
            int* ip;<br />
            t.d = 3.0;<br />
            ip = &amp;t.i;<br />
            return *ip;<br />
          }</p>
<p>The difference is that John&#8217;s program reads through the union with  fn2 (b.f0);</p>
]]></content:encoded>
	</item>
</channel>
</rss>
