473,698 Members | 2,883 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

[C99] local VLA with dimension given by a global var?

The system I am working on supports a subset of C99, among which
"standard-compliant VLAs".

I've already learnt that VLAs can't have global scope. My question is
whether I can safely declare a (local) VLA to have as its dimension a
global variable of type int:

short dim;

int main(void)
{

/* (...), possibly access/change value of dim */

{
int vla[dim];
}

/* (...) */

return 0;

}

If I understand the vary basics of how the compiler works this is a
trivial question, ie, in the code above the variable dim is just being
evaluated at that point and its value *at that point in time* is being
used to define the dimension of the array; is this correct? Ie, can I
safely this?

Thank you,

Mack

Nov 14 '05 #1
15 1635
j

"MackS" <ma***********@ hotmail.com> wrote in message
news:11******** **************@ c13g2000cwb.goo glegroups.com.. .
The system I am working on supports a subset of C99, among which
"standard-compliant VLAs".

I've already learnt that VLAs can't have global scope. My question is
whether I can safely declare a (local) VLA to have as its dimension a
global variable of type int:

short dim;

int main(void)
{

/* (...), possibly access/change value of dim */

{
int vla[dim];
}

/* (...) */

return 0;

}

If I understand the vary basics of how the compiler works this is a
trivial question, ie, in the code above the variable dim is just being
evaluated at that point and its value *at that point in time* is being
used to define the dimension of the array; is this correct? Ie, can I
safely this?

Thank you,

Mack


Yes, this is perfectly fine. 6.7.5.2#9 illustrates this.

--
j
Nov 14 '05 #2
On 19 Feb 2005 09:06:40 -0800, "MackS" <ma***********@ hotmail.com>
wrote in comp.lang.c:
The system I am working on supports a subset of C99, among which
"standard-compliant VLAs".

I've already learnt that VLAs can't have global scope. My question is
It has nothing to do with scope, it has to do with storage duration.
VLAs must have automatic storage duration, and can't have static
storage duration.
whether I can safely declare a (local) VLA to have as its dimension a
global variable of type int:

short dim;

int main(void)
{

/* (...), possibly access/change value of dim */

{
int vla[dim];
}

/* (...) */

return 0;

}

If I understand the vary basics of how the compiler works this is a
trivial question, ie, in the code above the variable dim is just being
evaluated at that point and its value *at that point in time* is being
used to define the dimension of the array; is this correct? Ie, can I
safely this?


Yes, the size of the VLA will be the value that the expression
evaluates to at the time the array is created.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #3
On 2005-02-19, Jack Klein <ja*******@spam cop.net> wrote:

It has nothing to do with scope, it has to do with storage duration.
VLAs must have automatic storage duration, and can't have static
storage duration.

Speaking of VLAs..

It seems that the standard doesn't specify how VLAs are implemented, although
the most obvious ways are:
1. stack (like the non-portable alloca())
2. malloc() on the heap

In both cases you can declare an absurdly large VLA so that there isn't enough
memory to allocate it. I haven't been able to find in the C99 standard what
happens then..

So what is the 'standard' way to handle an out-of-memory condition for VLAs?
There is no place to 'return NULL' as malloc() does..
Nov 14 '05 #4
Zeljko Vrba wrote:
On 2005-02-19, Jack Klein <ja*******@spam cop.net> wrote:
It has nothing to do with scope, it has to do with storage duration.
VLAs must have automatic storage duration, and can't have static
storage duration.


Speaking of VLAs..

It seems that the standard doesn't specify how VLAs are implemented, although
the most obvious ways are:
1. stack (like the non-portable alloca())
2. malloc() on the heap

In both cases you can declare an absurdly large VLA so that there isn't enough
memory to allocate it. I haven't been able to find in the C99 standard what
happens then..

So what is the 'standard' way to handle an out-of-memory condition for VLAs?
There is no place to 'return NULL' as malloc() does..


As this is not your problem but the implementation' s:
The program will die. If you are lucky, it will do so in a verbose
way. I would not nurse any expectations beyond a size of 64K...

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #5
On 2005-02-20, Michael Mair <Mi**********@i nvalid.invalid> wrote:

As this is not your problem but the implementation' s:
The program will die. If you are lucky, it will do so in a verbose
way. I would not nurse any expectations beyond a size of 64K...

OK, I'm not trying to start a flame here, but why would anyone use VLAs when
they are not guaranteed to always work and you cannot detect that? In all other
aspects of C the programmer is given a chance to handle the error (extending
your line of thought - why check for malloc() returning NULL? the library coud
just terminate the program..)

I think this is a crucial point missing from the standard. The standard
commitee should have taken this into account and specify some kind of
standard behaviour that is under programmer's control (e.g. delivery of a
signal for which a signal handler can be written, at least in the hosted
environments). Otherwise, each implementation will choose its own way of
letting the programmer know about the memory allocation failure (e.g.
#pragma VLA_alloc_failu re(handler_func ) and similar..) and soon there could
be several incompatible implementations and the C99 code which uses custom VLA
error handling as an extension won't be portable accross them any more..

What's worse, the implementation can *never* guarantee ANY size of VLA because
it depends on the current runtime environment (e.g. in one environment I could
possibly get 16M VLA, and in the other I couldn't get even 64k).

You can't even know in advance the maximum amount of memory needed for VLAs
so it could be preallocated at program startup (or the execution fails if it
can't be preallocated).

IMHO, these points combined with the absence of any standardized error handling
for VLA memory allocation failure makes them completely useless for programming
a seroius and robust application. It would be better if alloca() were
standardized.

Nov 14 '05 #6
On Sun, 20 Feb 2005 08:05:50 +0000 (UTC), Zeljko Vrba
<mo****@fly.srk .fer.hr> wrote:
On 2005-02-19, Jack Klein <ja*******@spam cop.net> wrote:

It has nothing to do with scope, it has to do with storage duration.
VLAs must have automatic storage duration, and can't have static
storage duration.
Speaking of VLAs..

It seems that the standard doesn't specify how VLAs are implemented, although
the most obvious ways are:
1. stack (like the non-portable alloca())
2. malloc() on the heap


A VLA has storage wherever it is used. If you say:

void func(int n)
{
char buff[n];
int x;
...
}

then both x and buff will be allocated in 'automatic' storage (whether
that is on "the stack" depends on whether that's what your compiler
uses).
In both cases you can declare an absurdly large VLA so that there isn't enough
memory to allocate it. I haven't been able to find in the C99 standard what
happens then..
Whatever usually happens when you allocate too much storage. It's
exactly the same as if you declared a fixed length array of the same
size (whatever you system does when it runs out of stack, for instance).
So what is the 'standard' way to handle an out-of-memory condition for VLAs?
There is no place to 'return NULL' as malloc() does..


There isn't one, the same as there isn't a 'standard' way to handle
recursion too deep, or declaring a 2GB 'normal' array in automatic
storage. If you are lucky your program will crash with a system error
and a core dump, if you are unlucky demons will erupt from your computer
and drag you down to the uttermost depths of world slime. The only
difference is that a compiler /might/ be able to trap a silly array size
at compile time with a fixed array (it doesn't have to, but it could be
done).

If you're really lucky the system will say "Oh, you want 57 petabytes of
memory? OK, I'll just go out and buy some for you, wait around a few
years..."

Chris C
Nov 14 '05 #7
Zeljko Vrba wrote:
On 2005-02-20, Michael Mair <Mi**********@i nvalid.invalid> wrote:
As this is not your problem but the implementation' s:
The program will die. If you are lucky, it will do so in a verbose
way. I would not nurse any expectations beyond a size of 64K...


OK, I'm not trying to start a flame here, but why would anyone use VLAs when
they are not guaranteed to always work and you cannot detect that? In all other
aspects of C the programmer is given a chance to handle the error (extending
your line of thought - why check for malloc() returning NULL? the library coud
just terminate the program..)

I think this is a crucial point missing from the standard. The standard
commitee should have taken this into account and specify some kind of
standard behaviour that is under programmer's control (e.g. delivery of a
signal for which a signal handler can be written, at least in the hosted
environments). Otherwise, each implementation will choose its own way of
letting the programmer know about the memory allocation failure (e.g.
#pragma VLA_alloc_failu re(handler_func ) and similar..) and soon there could
be several incompatible implementations and the C99 code which uses custom VLA
error handling as an extension won't be portable accross them any more..

What's worse, the implementation can *never* guarantee ANY size of VLA because
it depends on the current runtime environment (e.g. in one environment I could
possibly get 16M VLA, and in the other I couldn't get even 64k).

You can't even know in advance the maximum amount of memory needed for VLAs
so it could be preallocated at program startup (or the execution fails if it
can't be preallocated).

IMHO, these points combined with the absence of any standardized error handling
for VLA memory allocation failure makes them completely useless for programming
a seroius and robust application. It would be better if alloca() were
standardized.


In a way, you are right. However, even

double array[7000][7000];

can die at runtime without telling you why and while you still
have enough memory left...
If we added checks and safeguards and error states for each and
everything, then this new C would probably suffer from an even worse
lack of popularity than C99.

Back to VLAs: IMO, they are quite nice for reasonably small array
sizes but for larger array sizes I would always suggest to handle the
memory yourself i.e. explicitly allocate it and maybe implement a sparse
structure.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #8
On Sun, 20 Feb 2005 11:48:15 +0000 (UTC), Zeljko Vrba
<mo****@fly.srk .fer.hr> wrote:
On 2005-02-20, Michael Mair <Mi**********@i nvalid.invalid> wrote:

As this is not your problem but the implementation' s:
The program will die. If you are lucky, it will do so in a verbose
way. I would not nurse any expectations beyond a size of 64K...
OK, I'm not trying to start a flame here, but why would anyone use VLAs when
they are not guaranteed to always work and you cannot detect that? In all other
aspects of C the programmer is given a chance to handle the error (extending
your line of thought - why check for malloc() returning NULL? the library coud
just terminate the program..)


No, if you do

int main(int argc, char **argv)
{
long array[10000][10000];
printf("Hello world\n");
return 0;
}

then that is equally likely to fail at runtime with no way of catching
the error (trying to allocate 400 MB or more on the stack will probably
blow it). There is no difference. Or for that matter:

void func(int depth)
{
long array[10000];
if (depth > 0)
func(depth - 1);
}

int main(int argc, char **argv)
{
func(10000);
printf("Hello world\n");
return 0;
}

(it will run out of stack in the recursion).
I think this is a crucial point missing from the standard. The standard
commitee should have taken this into account and specify some kind of
standard behaviour that is under programmer's control (e.g. delivery of a
signal for which a signal handler can be written, at least in the hosted
environments). Otherwise, each implementation will choose its own way of
letting the programmer know about the memory allocation failure (e.g.
#pragma VLA_alloc_failu re(handler_func ) and similar..) and soon there could
be several incompatible implementations and the C99 code which uses custom VLA
error handling as an extension won't be portable accross them any more..
No, it is very unlikely that any implementors will put in any error
handling for it at all. As I pointed out above, there's nothing to stop
a program from trying to allocate too much on the stack with fixed
length arrays, why should VLAs be any different?

Note that in the version of the language which allows VLAs (C99) it is
also allowed to declare variables after other code:

void func(int len)
{
if (len < 1000)
{
int array[len];
/* do stuff */
}
else
{
/* do failure stuff */
}
}

If you try to force compilers (in the standard) to put in code to catch
every error then the code size will increase and the speed will drop and
you will find that no one uses the language.
What's worse, the implementation can *never* guarantee ANY size of VLA because
it depends on the current runtime environment (e.g. in one environment I could
possibly get 16M VLA, and in the other I couldn't get even 64k).
Yup. The same is true of any automatic variables. I have code which
assumes that a function can allocate a 16kB buffer locally, it will
break on some systems (on the systems where it is intended to run it is
safe, because I know that the stack is big enough there).
You can't even know in advance the maximum amount of memory needed for VLAs
so it could be preallocated at program startup (or the execution fails if it
can't be preallocated).
Nope. You can't know in advance anything at all about the system at run
time, it might crash just trying to load your program. We live in an
uncertain universe...
IMHO, these points combined with the absence of any standardized error handling
for VLA memory allocation failure makes them completely useless for programming
a seroius and robust application. It would be better if alloca() were
standardized.


Except that there are systems on which alloca() is difficult to
implement reliably as well (some programs test at install time whether
alloca() works and use a different mechanism if it doesn't), so the
standard would have to allow alloca() to always fail.

Personally, I think that all of the C99 features are pretty useless
until it can be reasonably guaranteed that almost everywhere will have a
conforming compiler and library. At the moment I can't portably use
VLAs, late declaration of variables, long long or many other features
I'd rather like to use...

Chris C
Nov 14 '05 #9
Michael Mair <Mi**********@i nvalid.invalid> writes:
Zeljko Vrba wrote:

[...]
Speaking of VLAs.. It seems that the standard doesn't specify how
VLAs are implemented, although
the most obvious ways are:
1. stack (like the non-portable alloca())
2. malloc() on the heap
In both cases you can declare an absurdly large VLA so that there
isn't enough memory to allocate it. I haven't been able to find in
the C99 standard what happens then.. So what is the 'standard' way
to handle an out-of-memory condition for VLAs? There is no place
to 'return NULL' as malloc() does..


As this is not your problem but the implementation' s:
The program will die. If you are lucky, it will do so in a verbose
way. I would not nurse any expectations beyond a size of 64K...


You can't assume that the program will die. Running out of memory for
a VLA invokes undefined behavior, just like running out of memory for
any other automatic variable.

Probably the only way to fix this would be to define a general
exception-handling mechanism for C, and require that running out of
space raises an exception that can be handled by the caller. (You
could provide some specific mechanism for VLAs, but that would be ugly
IMHO, since it wouldn't handle overflows for constant-sized arrays.)

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

47
3628
by: Andrey Tatarinov | last post by:
Hi. It would be great to be able to reverse usage/definition parts in haskell-way with "where" keyword. Since Python 3 would miss lambda, that would be extremly useful for creating readable sources. Usage could be something like: >>> res = where: >>> def f(x):
9
3726
by: Steve Jorgensen | last post by:
Hi all, I'm working on the schema for a database that must represent data about stock & bond funds over time. My connundrum is that, for any of several dimension fields, including the fund name itself, the dimension may be represented in different ways over time, and may split or combine from one period to the next. When querying from the database for an arbitrary time period, I need the data to be rolled up to the smallest extent...
13
476
by: jrefactors | last post by:
When people say C programming language, they mean ISO C89? The latest C is ISO C99, but I heard this is not commonly used. What's the differences between ISO C89 and ISO C99? Please advise. Thanks
0
1456
by: vsridhar420 | last post by:
I am trying to create a local cube from a cube which has a parant child dimension. Is the syntax for DIMENSION clause in the CREATE CUBE statement different for a parent-child dimension ? Because when I use syntax as with other dimensions, I am getting an error. Can Local cubes contain parent-child dimensions ? Thanks
193
9565
by: Michael B. | last post by:
I was just thinking about this, specifically wondering if there's any features that the C specification currently lacks, and which may be included in some future standardization. Of course, I speak only of features in the spirit of C; something like object-orientation, though a nice feature, does not belong in C. Something like being able to #define a #define would be very handy, though, e.g: #define DECLARE_FOO(bar) #define...
3
1543
by: Bernard | last post by:
Hello, I would like your advices on the following two functions which multiply two arrays. About Multiply_array, I think that this function is ISO C90, but for Product_array I have some doubts... You can see that Product_array try to use the new advantages of C99 (Variable Length Array) but still I'm a little surprised that this code can compile and run flawlessly (with gcc 3.2).
23
4001
by: Timothy Madden | last post by:
Hello all. I program C++ since a lot of time now and I still don't know this simple thing: what's the problem with local functions so they are not part of C++ ? There surely are many people who will find them very helpfull. gcc has them as a non-standard option, but only when compiling C language code, so I'm afraid there might be some obscure reason why local functions are not so easy to be dealt with in C++, which I do not yet know.
2
4562
by: Nathan Sokalski | last post by:
I have a multidimensional array declared as the following: Dim guesses(14, 5) As Integer I want to assign all values in a specific dimension to another array declared as follows:
55
6221
by: Zytan | last post by:
I see that static is more restricted in C# than in C++. It appears usable only on classes and methods, and data members, but cannot be created within a method itself. Surely this is possible in C# in some way? Or maybe no, because it is similar to a global variable (with its scope restricted) which C# is dead against? Zytan
0
8683
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9170
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9031
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8902
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8873
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
4623
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3052
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2339
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.