<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Clarkcox.com &#187; C99</title>
	<atom:link href="http://www.clarkcox.com/blog/tag/c99/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.clarkcox.com/blog</link>
	<description>Clark’s musings</description>
	<lastBuildDate>Mon, 15 Feb 2010 18:58:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>C99&#8242;s VLAs are evil</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/</link>
		<comments>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 04:14:27 +0000</pubDate>
		<dc:creator>Clark Cox</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[C99]]></category>

		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74</guid>
		<description><![CDATA[While, at first glance, the ability to define an array, whose length is determined at runtime from a variable, seems like a good idea. Hey, it’s very clean and easy to understand, and all of the normal array operations work[1]; there is one major flaw—there is no way to deal with errors. Variable Length Arrays, [...]]]></description>
			<content:encoded><![CDATA[<p>While, at first glance, the ability to define an array, whose length is determined at runtime from a variable, seems like a good idea. Hey, it’s very clean and easy to understand, and all of the normal array operations work<sup>[1]</sup>; there is one major flaw—there is no way to deal with errors.</p>
<p>Variable Length Arrays, in C99 are defined just like any other array, <em>except that the length doesn’t need to be a compile-time constant</em>:</p>
<p><code><br />
void foo(int size) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;int array[size];<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(int i=0; i&lt;size; ++i) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[i] = i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;...<br />
}<br />
</code></p>
<p>Calling the above function with any reasonable value will do the obvious thing, the array will be sized appropriately, will contain sequential numbers. <code>sizeof(array)</code> will even return <code>size*sizeof(int)</code>. For the common case, everything works, and everybody is happy. But what happens when a <code>size</code> is too large to fit on the stack? Who knows.<sup>[2]</sup></p>
<p>In the most common implementation of VLAs the compiler literally decrements the stack pointer by <code>size</code> and goes on it’s merry way, without regard to whether or not the stack pointer now points to an invalid address (or worse, a valid address somewhere inside of your program’s heap). If you’re lucky, and the stack pointer points to an invalid address, your program will likely crash. On the other hand, if you’re not so lucky, the seemingly innocuous function above will start trashing things in your program’s memory space; you may not catch it, you may have a strange, untraceable crash hours later, etc.. Needless to say, this can be quite difficult to debug.</p>
<p>The solution is to simply not use this feature of C99. If you&#8217;ve got a higher-level abstraction (such as <code>std::vector</code> in C++, <code>NSData</code> or <code>NSArray</code> in Cocoa) use that. If you really want to stick with pure, standard C, use <code>malloc()</code>/<code>free()</code><sup>[3]</sup>:</p>
<p><code><br />
void foo(int size) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *array = malloc(size * sizeof *array);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(!array) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Error out here<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(int i=0; i&lt;size; ++i) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array[i] = i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(array);<br />
}<br />
</code></p>
<ol class="footnotes"><li id="footnote_0_74" class="footnote">Even <code>sizeof</code> works, though that required a distasteful exception to the normal <code>sizeof</code> rules. Before VLAs, <code>sizeof</code> was <em>always</em> evaluated at compile time, and the resulting value was <em>always</em> a compile-time constant. When applied to VLAs, this obviously cannot be.</li><li id="footnote_1_74" class="footnote">I’m not joking. The official term is “undefined behavior”. In such a case, the C standard doesn’t specify <em>anything</em> about what happens.</li><li id="footnote_2_74" class="footnote">Don&#8217;t be tempted to use <code>alloca()</code>, it is not a standard C function, and has <em>exactly</em> the same issue that VLAs do</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
