Re: On VLAs and incomplete types
- From: Ben Bacarisse <ben.usenet@xxxxxxxxx>
- Date: Fri, 21 Mar 2008 15:19:10 +0000
Sensei <Sensei's e-mail is at Mac-dot-com> writes:
In (6.7.5.2) I read about the correct declaration of arrays, although
I don't understand how a variable is handled by the compiler in
declaring a VLA. As I understand, an array must be declared with an
integer size specifier:
int x[3];
That would give a complete type, and I can use x happily. If no
integer is specified, then
int x[];
would be an incomplete type. This quite puzzles me, since I don't
understand how x[] could then be used in a code block.
It can't be.
I can only
think about a function with two parameters, the incomplete array and
the size. Is it possible to make use of that variable in other ways?
No, but I think you are being confused by one the things that most
frequently confuses people new to C. The [] syntax in a parameter
specification has a special meaning. It does not denote an incomplete
type -- it is essentially the same as declaring that parameter to be a
pointer. In other words:
void f(int x[]);
and
void f(int *x);
are the same. This only applies to the "first" set of []s. Thus
void f(int x[][])
*is* illegal because it declares x as having an incomplete element type.
None of this applies to array objects. Trying to define an array x,
like this:
int x[];
as an automatic variable (i.e. in the body of a function) is wrong.
You *can* use empty []s if an initializer is used to give the size:
int x[] = {1, 2, 3};
is OK. There are some special cases when [] is used in an array
declaration at file scope (outside any function body) but it is best
to put these to one side for the moment.
The other doubt is about VLAs. If some variable is specified instead
of a constant, then the variable should be in the block. In the
document I see a prototype and a variable inside the code block:
void fvla(int m, int C[m][m])
...
int D[m];
My question is probably stupid, but how are C and D handled by the
compiler?
This is a common question. How does this work? What is the compiler
doing here? The trouble with this sort of question is that you are
asking for more than you need. Why add understanding the C compiler
to the task of understanding C? Sometimes it helps but with more
complex languages is definitely does not. (For example, it is much
easier to understand what a Haskell program means, than it is to see
how the compiler make it work.)
Any, I'll have a go... In this program:
void f(int m, int C[m][m])
{
int D[m];
...
}
int main(void)
{
int x[4][4];
f(4, x);
return 0;
}
x is simple a 2D array of 4 arrays or 4 ints. It is passed to f (like
all arrays are passed) as a pointer to its first element. x is
converted to a pointer of type 'int (*)[4]'. f would be the same if
it were declared:
void f(int m, int C[][m]);
or
void f(int m, int (*C)[m]);
Only the second m matters to the compiler. This is because, given a
pointer to that first array of 4 ints, all the compiler needs to know
is how to get to the next element. It needs to know the element size,
not how many elements there are.
When the program flow reaches the declaration of D, space for an array
m (in this case 4) ints is allocated. This storage lasts until the
function returns, so it is natural for the compiler to take the
storage from the same place it uses for other automatic variables --
usually this is from a stack.
My concerns are about some code like the following (mixed
code and variables, since it is C99):
/* checks about argc and argv */
int a = atoi(argv[1]);
/* follows some check about a */
int x[a];
I know it's risky, but it's allowed, isn't it?
Yes.
Is x allocated on the
fly as we enter the code block (somehow, on the heap or by any other
non C-related means)
Well put. How or where does not matter. It is likely to allocated
from a stack ("the" stack if the compiler is using only one).
and then subsequently freed when exit?
The way I used to put it was: the storage lasts until the program flow
passes the end of the variable's scope (unless the program exits before
that). It is surprisingly hard to get the words exactly right, but
most people find the intent more natural than the wording used to
explain it!
Then what
are the advantages (not counting the "syntactic sugar" I can think of)
of having VLAs into the standard?
It allows you to have arrays of variable size, efficiently allocated.
malloc and free will usually be slower and you need to do the freeing.
The real advantage, though, comes with code like your 2D array
parameter called C. Such things are simpler with VLA parameters.
--
Ben.
.
- Follow-Ups:
- Re: On VLAs and incomplete types
- From: Old Wolf
- Re: On VLAs and incomplete types
- From: Sensei
- Re: On VLAs and incomplete types
- References:
- On VLAs and incomplete types
- From: Sensei
- On VLAs and incomplete types
- Prev by Date: Re: prpject topic on C
- Next by Date: Wide character, portable function to parse words like O'Clock as one word?
- Previous by thread: On VLAs and incomplete types
- Next by thread: Re: On VLAs and incomplete types
- Index(es):
Relevant Pages
|