Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Variable-length arrays: should they be used at all?

Reply
Thread Tools

Variable-length arrays: should they be used at all?

 
 
David Resnick
Guest
Posts: n/a
 
      06-26-2012
On Tuesday, June 26, 2012 3:47:08 PM UTC-4, Rui Maciel wrote:
> Undoubtedly, VLAs are convenient. Yet, with that convenience comes the
> danger of making an otherwise flawless program susceptible to nasty memory
> allocation problems. No matter how convenient VLAs might be, having to
> handle unexplainable segfaults that can't be avoided with the dilligent use
> of safeguards may not be an acceptable tradeoff.


Yep, they should be used with caution. Mind you, the same arguments apply to using recursion. How deeply you can safely recurse, and the consequencesif you go too deep, also murky. Had a recursion related crash where somebody markedly increased the size of an automatic buffer in moderately deeplyrecursive code.
 
Reply With Quote
 
 
 
 
Malcolm McLean
Guest
Posts: n/a
 
      06-27-2012
בתאריך יום שלישי, 26 ביו*י 2012 21:51:12 UTC+1, מאת David Resnick:
>
> Yep, they should be used with caution. Mind you, the same arguments apply to using recursion. How deeply you can safely recurse, and the consequences if you go too deep, also murky. Had a recursion related crash where somebody markedly increased the size of an automatic buffer in moderately deeply recursive code.
>

The difference is that recursion is usually logarithmic in depth. A malicious or careless user has to construct a degenerate tree. That's a lot harderthan simply declaring that a company has 4 billion employees.

 
Reply With Quote
 
 
 
 
jacob navia
Guest
Posts: n/a
 
      06-27-2012
Le 26/06/12 21:18, Stefan Ram a crit :
> jacob navia <> writes:
>> char buffer[iList.GetSize(NULL)];
>> List *L = (List *)&buffer[0];
>> iList.InitList(L);

>
> You can get the same with
>
> ListBuffer buffer;
> List * L =( List * )&buffer;
> iList.InitList( L );
>


Sorry but I do not understand that: what would be "ListBuffer"?

A predefined type of buffer long enough to hold a list header
structure?

If that is the case then its length MUST be known to the compiler, and
that means that the definition of the list header structure must be
disclosed, what we want to avoid precisely.


 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      06-27-2012
On 06/27/12 08:09 AM, Keith Thompson wrote:
> Rui Maciel<> writes:
>> jacob navia wrote:
>>> VLAs are indispensable when you want to avoid unnecessary calls
>>> to the expensive malloc function.

>>
>> But what about the inability to gracefully recover from a memory allocation
>> error? If a VLA is defined with the wrong size at the wrong moment then it
>> appears that it isn't possible to do anything about it, nor is it even
>> possible to put in place any safeguard to avoid that. In fact, are there
>> any scenarios where a VLA defined with an arbitrary size is guaranteed to
>> work as expected?

>
> No (unless the implementation defines its own error-detection
> mechanism).
>
> But the same applies to old-style constant-size arrays. If you declare
>
> double mat[100][100];
>
> either at block scope or at file scope, there's no mechanism to detect
> an allocation failure.


But you can do a static analysis.

--
Ian Collins
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      06-27-2012
Le 27/06/12 07:50, Ian Collins a crit :
> On 06/27/12 08:09 AM, Keith Thompson wrote:
>> Rui Maciel<> writes:
>>> jacob navia wrote:
>>>> VLAs are indispensable when you want to avoid unnecessary calls
>>>> to the expensive malloc function.
>>>
>>> But what about the inability to gracefully recover from a memory
>>> allocation
>>> error? If a VLA is defined with the wrong size at the wrong moment
>>> then it
>>> appears that it isn't possible to do anything about it, nor is it even
>>> possible to put in place any safeguard to avoid that. In fact, are
>>> there
>>> any scenarios where a VLA defined with an arbitrary size is
>>> guaranteed to
>>> work as expected?

>>
>> No (unless the implementation defines its own error-detection
>> mechanism).
>>
>> But the same applies to old-style constant-size arrays. If you declare
>>
>> double mat[100][100];
>>
>> either at block scope or at file scope, there's no mechanism to detect
>> an allocation failure.

>
> But you can do a static analysis.
>


lcc-win was ported to a 16 bit Analog Devices chip with something like
40K RAM available.

There was no stack, and the stack was created by the compiler using
a memory array: this implied a static analaysis.

Recursion was forbidden (coudln't be analyzed well) and indirect
recursion was detected: function A calls B that calls C that calls A.

If you are doing that, VLA's are of course off limits. But, as far as
I know, recursion is allowed in C and nobody is screaming to
eliminate it because in some RAM constrained environments it could
lead to crashes.

We have to separate the C language from the implementations of C
in very constrained environments.
 
Reply With Quote
 
gwowen
Guest
Posts: n/a
 
      06-27-2012
On Jun 27, 6:57*am, jacob navia <ja...@spamsink.net> wrote:

> Recursion was forbidden (coudln't be analyzed well) and indirect
> recursion was detected:


....

> recursion is allowed in C and nobody is screaming to
> eliminate it because in some RAM constrained environments it could
> lead to crashes.


Clearly, some people (e.g. the lcc authors) *are* eliminating
recursion - in certain cases - for *precisely* those reasons.

Like recursion, VLAs are (recursion is) fine as long as you *know* the
VLA length (recursion depth) is going to remain pretty small relative
to your stack. If you know that, no problem. If you don't, something
may blow in a horrible way.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      06-27-2012
jacob navia <> writes:
<snip>
> lcc-win was ported to a 16 bit Analog Devices chip with something like
> 40K RAM available.
>
> There was no stack, and the stack was created by the compiler using
> a memory array: this implied a static analaysis.
>
> Recursion was forbidden (coudln't be analyzed well) and indirect
> recursion was detected: function A calls B that calls C that calls A.


If recursion is forbidden, would it not be worthwhile having a single
static area for each function? This is what some IBM compilers used to
do (and they may still do for all I know).

<snip>
--
Ben.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      06-27-2012
On 6/27/2012 8:50 AM, Ben Bacarisse wrote:
> jacob navia <> writes:
> <snip>
>> lcc-win was ported to a 16 bit Analog Devices chip with something like
>> 40K RAM available.
>>
>> There was no stack, and the stack was created by the compiler using
>> a memory array: this implied a static analaysis.
>>
>> Recursion was forbidden (coudln't be analyzed well) and indirect
>> recursion was detected: function A calls B that calls C that calls A.

>
> If recursion is forbidden, would it not be worthwhile having a single
> static area for each function? This is what some IBM compilers used to
> do (and they may still do for all I know).


A shared stack would use less memory, unless there was some
execution path in which all functions were active simultaneously.

Per-function (or per-block) static storage might be attractive
on machines where stack-relative addressing is cumbersome. I recall
that Turbo Pascal on the Z80 used this technique. It allowed
recursive functions and procedures, though: You told the compiler
which could be called recursively, it generated prologue and
epilogue code to swap the static data out to a stack and back, and
each invocation re-used the same static area. This wouldn't work
for C, of course, since you wouldn't want an auto variable to be
moved after you'd formed a pointer to it ...

--
Eric Sosman
d


 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      06-27-2012
jacob navia <> writes:
>Le 26/06/12 21:18, Stefan Ram a crit :
>>ListBuffer buffer;
>>List * L =( List * )&buffer;
>>iList.InitList( L );

>Sorry but I do not understand that: what would be "ListBuffer"?
>A predefined type of buffer long enough to hold a list header
>structure?


Yes, something like

struct { char dummy[ LIST_SIZE ]; } ListBuffer;

 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      06-27-2012
Rui Maciel <> writes:

> In the thread "Learning C as an existing programmer", an interesting
> discussion arose over the use of variable-length arrays (VLAs), specifically
> the dangers they pose by not providing a way to detect potential memory
> allocation bugs.
>
> GCC's page on variable-length arrays says nothing about what to expect when
> a VLA is too large to handle.[1] In addition, what has been said in GCC's
> mailing list about avoiding segfaults induced by huge VLAs isn't very
> reassuring.[2]
>
> With this in mind, and considering that VLAs were made optional in C11, is
> it a good idea to simply refuse using them?


There are two distinct concerns here. Let's take them one at a
time.

First, encountering a VLA declaration during execution may blow
the stack and crash, and there is no portable way to detect or
deal with that. However, it is easy for implementations to
provide a way of doing that, without adding any new language
constructs, as I explained in another posting.

Second, VLAs have not been implmented by some vendors (a certain
laggard major software company comes to mind here), and VLA
support is optional in C11, presumably so those vendors can claim
full C11 compliance without having to provide VLA support.

The flip side to the second concern is that many or most major
implementations (at least hosted implementations) do provide VLA
support, and will continue to do so under C11, despite its being
optional. The laggards will keep being laggards, whether VLA
support is optional or not, because they think their user base
doesn't care about it (or perhaps because they think their user
base has to accept what they do whether the user base cares about
it or not).

The flip side of the first concern is that, one, it often isn't a
big deal in practice; two, implementors should be encouraged to
supply a mechanism for detecting/handling VLA allocation failure,
since it is easy to provide such a mechanism; and three, VLA
support provides an important benefit that does not have the
associated risk of undetectable allocation failure, namely,
variably modified types and more specifically pointers to VLAs,
which are useful even if VLA objects are never declared.

Personally, I find VLA support useful and convenient, whether
using VLAs themselves or just pointers to them, and in a wider
variety of circumstances than I originally expected. Vendors
and implementors will provide VLA support if developers use
them, and very likely won't if they don't. So my conclusion
is somewhat the opposite of yours -- developers *should* use
VLAs and variably modified types whenever they are useful and
convenient to express the programming task at hand, and also
should encourage and prevail upon vendors and implementors to
supply better VLA support, such as a mechanism for detecting
and handling allocation failure like the one described in
another thread. VLA support is both convenient and useful;
if demand for it is high enough, implementations that provide
VLAs will become both better and more ubiquitous.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
gems should *not be case sensitive.. or should they? botp Ruby 6 10-04-2010 11:42 PM
MCSE exam # 70-216. They they show you the score?? Jack Black Microsoft Certification 1 12-09-2004 11:54 PM
When they're gone, they could be gone for good... Richard DVD Video 10 06-02-2004 07:13 AM
Is "They Shoot Horses, Don't They?" getting a re-release? Maverick DVD Video 1 10-25-2003 02:17 AM
they turn, they power, they make nice pics Keith and Jenn Z. Digital Photography 0 09-21-2003 04:16 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57