<?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: C99&#8242;s VLAs are evil</title>
	<atom:link href="http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/</link>
	<description>Clark’s musings</description>
	<lastBuildDate>Fri, 29 Jul 2011 20:57:28 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: Clark Cox on VLAs &#124; Clark Cox on VLAs iphone &#124; Clark Cox on VLAs iphone 4 &#124; Iphone Mobile Phones &#62; Iphone 4 Prices &#62; Iphone Phones</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-3296</link>
		<dc:creator>Clark Cox on VLAs &#124; Clark Cox on VLAs iphone &#124; Clark Cox on VLAs iphone 4 &#124; Iphone Mobile Phones &#62; Iphone 4 Prices &#62; Iphone Phones</dc:creator>
		<pubDate>Sat, 07 Aug 2010 01:58:09 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-3296</guid>
		<description>[...] III, a Cocoa developer and fairly frequent contributor to the cocoa-dev mailing list, points out a major flaw in C99&#8217;s variable length arrays (VLAs) on his blog today. While it is nice to be able to allocate arrays on the stack, I&#8217;m with Clark on this one: use [...]</description>
		<content:encoded><![CDATA[<p>[...] III, a Cocoa developer and fairly frequent contributor to the cocoa-dev mailing list, points out a major flaw in C99&#8217;s variable length arrays (VLAs) on his blog today. While it is nice to be able to allocate arrays on the stack, I&#8217;m with Clark on this one: use [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rohar</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-3265</link>
		<dc:creator>Rohar</dc:creator>
		<pubDate>Wed, 04 Aug 2010 02:49:45 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-3265</guid>
		<description>Compilers like gcc is happy even if you pass -1 to a variable-length array.  In this case, sizeof(array) is  0xFFFFFFFC.</description>
		<content:encoded><![CDATA[<p>Compilers like gcc is happy even if you pass -1 to a variable-length array.  In this case, sizeof(array) is  0xFFFFFFFC.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cyberscorpio</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-1756</link>
		<dc:creator>cyberscorpio</dc:creator>
		<pubDate>Fri, 26 Feb 2010 02:11:14 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-1756</guid>
		<description>And the code can be wrapped in macro to simplify the works :)

#define GET_BUFFER(size) ....
#define FREE_BUFFER(...)</description>
		<content:encoded><![CDATA[<p>And the code can be wrapped in macro to simplify the works :)</p>
<p>#define GET_BUFFER(size) &#8230;.<br />
#define FREE_BUFFER(&#8230;)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cyberscorpio</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-1755</link>
		<dc:creator>cyberscorpio</dc:creator>
		<pubDate>Fri, 26 Feb 2010 02:07:34 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-1755</guid>
		<description>How about to do so:

void foo(int size) {
    int asize = size;
    if (asize &gt; 1024)
        asize = 1;
    int buffer[asize];
    int *array = buffer;
    if (asize != size)
          array = malloc(size * sizeof *array);
    
    if(!array) {
        //Error out here
        return;
    }


    for(int i=0; i&lt;size; ++i) {
        array[i] = i;
    }
    ...

    if (array != buffer)
        free(array);
}</description>
		<content:encoded><![CDATA[<p>How about to do so:</p>
<p>void foo(int size) {<br />
    int asize = size;<br />
    if (asize > 1024)<br />
        asize = 1;<br />
    int buffer[asize];<br />
    int *array = buffer;<br />
    if (asize != size)<br />
          array = malloc(size * sizeof *array);</p>
<p>    if(!array) {<br />
        //Error out here<br />
        return;<br />
    }</p>
<p>    for(int i=0; i<size; ++i) {<br />
        array[i] = i;<br />
    }<br />
    &#8230;</p>
<p>    if (array != buffer)<br />
        free(array);<br />
}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: NoN@me</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-912</link>
		<dc:creator>NoN@me</dc:creator>
		<pubDate>Sat, 10 Oct 2009 14:27:46 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-912</guid>
		<description>All normal compilers do stack allocations correctly, not by simply decrementing the stack pointer. For example (gcc (GCC) 3.4.2 (mingw-special)):
.00401730: 51                           push        ecx
.00401731: 89E1                         mov         ecx,esp
.00401733: 83C108                       add         ecx,008 ;&quot;◘&quot;
.00401736: 3D00100000                   cmp         eax,000001000 ;&quot;  ► &quot;
.0040173B: 7210                         jb         .00040174D  -----↓ (1)
.0040173D: 81E900100000                 sub         ecx,000001000 ;&quot;  ► &quot;
.00401743: 830900                       or          d,[ecx],000 ;&quot; &quot;
.00401746: 2D00100000                   sub         eax,000001000 ;&quot;  ► &quot;
.0040174B: EBE9                         jmps       .000401736  -----↑ (2)
.0040174D: 29C1                         sub         ecx,eax
.0040174F: 830900                       or          d,[ecx],000 ;&quot; &quot;
.00401752: 89E0                         mov         eax,esp
.00401754: 89CC                         mov         esp,ecx
.00401756: 8B08                         mov         ecx,[eax]
.00401758: 8B4004                       mov         eax,[eax][04]
.0040175B: FFE0                         jmp         eax</description>
		<content:encoded><![CDATA[<p>All normal compilers do stack allocations correctly, not by simply decrementing the stack pointer. For example (gcc (GCC) 3.4.2 (mingw-special)):<br />
.00401730: 51                           push        ecx<br />
.00401731: 89E1                         mov         ecx,esp<br />
.00401733: 83C108                       add         ecx,008 ;&#8221;◘&#8221;<br />
.00401736: 3D00100000                   cmp         eax,000001000 ;&#8221;  ► &#8221;<br />
.0040173B: 7210                         jb         .00040174D  &#8212;&#8211;↓ (1)<br />
.0040173D: 81E900100000                 sub         ecx,000001000 ;&#8221;  ► &#8221;<br />
.00401743: 830900                       or          d,[ecx],000 ;&#8221; &#8221;<br />
.00401746: 2D00100000                   sub         eax,000001000 ;&#8221;  ► &#8221;<br />
.0040174B: EBE9                         jmps       .000401736  &#8212;&#8211;↑ (2)<br />
.0040174D: 29C1                         sub         ecx,eax<br />
.0040174F: 830900                       or          d,[ecx],000 ;&#8221; &#8221;<br />
.00401752: 89E0                         mov         eax,esp<br />
.00401754: 89CC                         mov         esp,ecx<br />
.00401756: 8B08                         mov         ecx,[eax]<br />
.00401758: 8B4004                       mov         eax,[eax][04]<br />
.0040175B: FFE0                         jmp         eax</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: MRG</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-347</link>
		<dc:creator>MRG</dc:creator>
		<pubDate>Thu, 09 Jul 2009 05:24:33 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-347</guid>
		<description>I disagree about the VLA having very little benefit.  For numerical programming with a lot of matrices VLA&#039;s can result in much cleaner code.  The lack of VLA&#039;s in pre C99 is one reason C was never widely used for numerical programming.</description>
		<content:encoded><![CDATA[<p>I disagree about the VLA having very little benefit.  For numerical programming with a lot of matrices VLA&#8217;s can result in much cleaner code.  The lack of VLA&#8217;s in pre C99 is one reason C was never widely used for numerical programming.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: MRG</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-346</link>
		<dc:creator>MRG</dc:creator>
		<pubDate>Thu, 09 Jul 2009 05:24:14 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-346</guid>
		<description>Sure, that&#039;s right, passing the VLA to the function will not lead to a stack overflow.

Here is another example of allocating a VLA with malloc that is sometimes useful

void func(int m, int n) {

     int i, j;
     double (*data)[n];

     data = malloc(m * n * sizeof(double));

     for (i = 0; i &lt; m; ++i) {
          for (j = 0; j &lt; n; ++j) {
               data[i][j] = 0.;
          }
     }

     /* do more stuff with data here */

     free((void *) data);
}</description>
		<content:encoded><![CDATA[<p>Sure, that&#8217;s right, passing the VLA to the function will not lead to a stack overflow.</p>
<p>Here is another example of allocating a VLA with malloc that is sometimes useful</p>
<p>void func(int m, int n) {</p>
<p>     int i, j;<br />
     double (*data)[n];</p>
<p>     data = malloc(m * n * sizeof(double));</p>
<p>     for (i = 0; i &lt; m; ++i) {<br />
          for (j = 0; j &lt; n; ++j) {<br />
               data[i][j] = 0.;<br />
          }<br />
     }</p>
<p>     /* do more stuff with data here */</p>
<p>     free((void *) data);<br />
}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Clark Cox</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-317</link>
		<dc:creator>Clark Cox</dc:creator>
		<pubDate>Sat, 04 Jul 2009 22:30:14 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-317</guid>
		<description>The case of using the VLA in the function parameter is a different issue. It won&#039;t lead to the same kind of stack corruption, as you aren&#039;t allocating that array on the stack, you&#039;re merely receiving a pointer to it. In that case, you&#039;re free to validate the value of (n) before using the array; you don&#039;t have that option for arrays with automatic storage.

The way C handles arrays and pointers in general is simultaneously one of its greatest strengths and one of its greatest weaknesses. VLA&#039;s serve to obfuscate the issue, with very little benefit, and make it even easier to crash your program.</description>
		<content:encoded><![CDATA[<p>The case of using the VLA in the function parameter is a different issue. It won&#8217;t lead to the same kind of stack corruption, as you aren&#8217;t allocating that array on the stack, you&#8217;re merely receiving a pointer to it. In that case, you&#8217;re free to validate the value of (n) before using the array; you don&#8217;t have that option for arrays with automatic storage.</p>
<p>The way C handles arrays and pointers in general is simultaneously one of its greatest strengths and one of its greatest weaknesses. VLA&#8217;s serve to obfuscate the issue, with very little benefit, and make it even easier to crash your program.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: GRM</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-316</link>
		<dc:creator>GRM</dc:creator>
		<pubDate>Sat, 04 Jul 2009 21:36:53 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-316</guid>
		<description>I agree with SNF.  This is not a new problem at all.  One should not allocate large work arrays in functions in this way.  They should allocate them dynamically.  If one does not want to worry about calling free() for every malloc() they can use alloca().

C99 VLA does have a benefit for multi dimensional arrays.  For example:

void func(int n, double data[][n]) {
...
}

This cannot be done in C unless the number of columns is static.  This can have huge benefits in scientific programming when pointer arrays cannot be used effectively.</description>
		<content:encoded><![CDATA[<p>I agree with SNF.  This is not a new problem at all.  One should not allocate large work arrays in functions in this way.  They should allocate them dynamically.  If one does not want to worry about calling free() for every malloc() they can use alloca().</p>
<p>C99 VLA does have a benefit for multi dimensional arrays.  For example:</p>
<p>void func(int n, double data[][n]) {<br />
&#8230;<br />
}</p>
<p>This cannot be done in C unless the number of columns is static.  This can have huge benefits in scientific programming when pointer arrays cannot be used effectively.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: SNF</title>
		<link>http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/comment-page-1/#comment-124</link>
		<dc:creator>SNF</dc:creator>
		<pubDate>Thu, 07 May 2009 14:48:57 +0000</pubDate>
		<guid isPermaLink="false">http://www.clarkcox.com/blog/?p=74#comment-124</guid>
		<description>You know, this really isn&#039;t a new problem; it applies to compile-time-constant-length stack arrays as well.  How do you know there&#039;s room on the stack to allocate, say, int[1024]?  You don&#039;t.

You *assume* the runtime has allocated enough room for the stack, and that your function isn&#039;t being called at a point when the stack has grown to the point where your array doesn&#039;t fit.

The solution is the same in both cases:  Use the stack responsibly.  Don&#039;t use it to store enormous arrays, and only use VLAs when the length is being passed or calculated from trusted data.  Also, assert() is your friend.</description>
		<content:encoded><![CDATA[<p>You know, this really isn&#8217;t a new problem; it applies to compile-time-constant-length stack arrays as well.  How do you know there&#8217;s room on the stack to allocate, say, int[1024]?  You don&#8217;t.</p>
<p>You *assume* the runtime has allocated enough room for the stack, and that your function isn&#8217;t being called at a point when the stack has grown to the point where your array doesn&#8217;t fit.</p>
<p>The solution is the same in both cases:  Use the stack responsibly.  Don&#8217;t use it to store enormous arrays, and only use VLAs when the length is being passed or calculated from trusted data.  Also, assert() is your friend.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

