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?

 
 
Rui Maciel
Guest
Posts: n/a
 
      06-26-2012
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?


Rui Maciel

[1] http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
[2] http://gcc.gnu.org/ml/gcc/2007-01/msg00179.html
 
Reply With Quote
 
 
 
 
Stefan Ram
Guest
Posts: n/a
 
      06-26-2012
Rui Maciel <(E-Mail Removed)> writes:
>With this in mind, and considering that VLAs were made optional in C11, is
>it a good idea to simply refuse using them?


Common auto objects just differ in the quantity, but not in
the quality of the problem of automatic storage allocation.

One would like to have a call »size_t auto();« so that there
are at least auto() bytes still available for automatic
storage allocation.

int factorial( int const n )
{ if( auto() < sizeof( int )*8 + 1024 )return -1;
else
{ int const fn1 = factorial( n - 1 );
if( fn1 == -1 )return -1;
else return n * fn1; }}

(The expression »sizeof( int )*8 + 1024« above is just a
heuristic estimation chosen to very probably still be
sufficient for another function call. Also, an implementation
is expected to lie on the safe side, i.e., to return a
value that is somewhat smaller than the actual amount
available, by at least a small multiple of the minimum
size of a stack frame.)

(Since »auto« is a keyword, »auto()« is no function call,
but a kind of an operator expression with a special meaning
to the compiler.)

 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      06-26-2012
On 6/26/2012 10:28 AM, Rui Maciel wrote:
> 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?


It may come down to personal preference, and to the "kind" of
programming you're doing. VLA's are a great notational convenience,
especially for multi-dimensional arrays. Also, they relieve the
coder of worrying about releasing memory, which can be a help if
there are multiple ways to exit the allocating block.

The disadvantage, of course, is that there is no portable way
to detect an allocation failure. Even if the program is unable to
complete its work in the event of malloc() failure, the ability to
detect it allows the coder to arrange for a clean shutdown rather
than an abrupt ka-BOOM. But undetectable allocation failure is
not unique to VLA's, as your reference [2] indicates: The problem
in that thread was an auto array of fixed size that happened to be
too large. Pretty much any block might fail to allocate memory for
its auto variables, even if its own space requirement is modest: A
paltry four ints could be the straw that breaks the camel's stack.

The fact that VLA's became optional with C11 may or may not
be important. Support for IEEE floating-point has been optional
for years, but that doesn't seem to have stopped people from
relying on it. What will happen to VLA support in future compilers
remains to be seen.[*]

Perhaps a bigger issue than VLA's possible disappearance is
their tardy APpearance: C99 support has not been quick to arrive,
and even today it might not be unusual to encounter an implementation
that lacked VLA's. Between "They may be going away" and "They're not
even here yet," VLA's might be seen as diminishing the portability
of code that uses them.

Okay, so: The pros are notational convenience and relief from
some memory-management burden, the cons are additional chances for
ka-BOOM and possible portability/version issues. Wrap it all up
in your own personal preference and your project's needs, and make
your own call. Personally, I avoid 'em -- but YMMV.

[*] I find it distressing that successive Standards seem to
be turning away from the principle expressed in the Rationale:

"Beyond this two-level scheme [hosted and freestanding],
no additional subsetting is defined for C, since the C89
Committee felt strongly that too many levels dilutes the
effectiveness of a standard."

That's from the C99 Rationale, but I think it's a paraphrase from
the original (which I saw once but don't have). If the C11 Rationale
includes this text, it might be accused of being insincere.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d


 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      06-26-2012
Le 26/06/12 16:28, Rui Maciel a écrit :
> 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?
>
>
> Rui Maciel
>
> [1] http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
> [2] http://gcc.gnu.org/ml/gcc/2007-01/msg00179.html
>


VLAs are indispensable when you want to avoid unnecessary calls
to the expensive malloc function.

For instance if you have some structure X that is hidden as an opaque
structure to avoid that client code

You can of course get the size of the hidden structure by calling a
library function.

Example:

int main(void)
{
char buffer[iList.GetSize(NULL)];
List *L = (List *)&buffer[0];
iList.InitList(L);

// Here you use your list.

iList.Clear(L);
/// Here you do not need to call iList.Finalize since
// you haven't allocated it with malloc
}

The crucial call here is:
char buffer[iList.GetSize(NULL)];

This allows tghe library to return the size of the structure WITHOUT
disclosing its internal state. This is very important.

The alternatives are very bad since you would have to

#define SIZEOF_LIST_HEADER 56

and do not forget to update that each time your List structure changes.

 
Reply With Quote
 
Jens Gustedt
Guest
Posts: n/a
 
      06-26-2012
Am 26.06.2012 16:28, schrieb Rui Maciel:
> 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?


- Pointers to VLA are very convenient when you have to deal with
multi-dimensional arrays
- VLA types themselves greatly improve readability of malloc calls
- VLA are really great help for function calls

double (*A)[n] = malloc(sizeof(double[n][n]));

void init(size_t n, double A[n][n]) {
for (size_t i = 0; i < n; ++i)
for (size_t j = 0; j < n; ++j)
A[i][j] = 0.0;

}

Jens
 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      06-26-2012
jacob navia <(E-Mail Removed)> 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 );

 
Reply With Quote
 
Rui Maciel
Guest
Posts: n/a
 
      06-26-2012
Jens Gustedt wrote:

> - Pointers to VLA are very convenient when you have to deal with
> multi-dimensional arrays
> - VLA types themselves greatly improve readability of malloc calls
> - VLA are really great help for function calls
>
> double (*A)[n] = malloc(sizeof(double[n][n]));
>
> void init(size_t n, double A[n][n]) {
> for (size_t i = 0; i < n; ++i)
> for (size_t j = 0; j < n; ++j)
> A[i][j] = 0.0;
>
> }


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.


Rui Maciel
 
Reply With Quote
 
Rui Maciel
Guest
Posts: n/a
 
      06-26-2012
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?


Rui Maciel
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-26-2012
Rui Maciel <(E-Mail Removed)> writes:
> Jens Gustedt wrote:
>> - Pointers to VLA are very convenient when you have to deal with
>> multi-dimensional arrays
>> - VLA types themselves greatly improve readability of malloc calls
>> - VLA are really great help for function calls
>>
>> double (*A)[n] = malloc(sizeof(double[n][n]));
>>
>> void init(size_t n, double A[n][n]) {
>> for (size_t i = 0; i < n; ++i)
>> for (size_t j = 0; j < n; ++j)
>> A[i][j] = 0.0;
>>
>> }

>
> 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.


Except that the code you quoted isn't subject to unexplainable
segfaults. It uses a VLA type, but there are no VLA objects with
automatic storage duration; A is allocated with malloc(), which returns
NULL on failure.

The use of a VLA type makes indexing more convenient.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-26-2012
Rui Maciel <(E-Mail Removed)> 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.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
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