Redundant statement in the Standard?

R

Richard Tobin

I think you're still mistaken. As far as I can tell, VLAs of VLAs
are permitted.
[/QUOTE]
I differ.

The standard itself has examples of multi-dimensional VLAs, such as

int c[n][n][6][m];

which - like all multi-dimensional arrays in C - are arrays of arrays.
Arrays need to be composed of equal sized objects.

All arrays of VLAs in C are arrays of equal-sized VLAs.
You could have an array of pointers to VLAs, though.

You can have that too.

-- Richard
 
C

CBFalconer

Keith said:
You snipped the part where I asked you to provide a citation from
the standard to support your claim. You also snipped the example
demonstrating a VLA of VLAs.

The size of a VLA is fixed at runtime when it's created, and all
the elements of an array of VLAs must have the same size.

If you have a specific reason to think this isn't allowed, I'd
love to hear it (and somebody should submit bug reports against
the four different compilers that didn't complain about VLAs of
VLAs).

I think we are talking about different things. As far as I am
concerned once the various 'component' VLAs have been constituted,
they have to be the same size, and thus are no longer VLAs. Now
they can be arrayed. I certainly haven't studied the standard
about this, and am just trying to apply common sense.
 
K

Keith Thompson

CBFalconer said:
I think we are talking about different things. As far as I am
concerned once the various 'component' VLAs have been constituted,
they have to be the same size, and thus are no longer VLAs. Now
they can be arrayed. I certainly haven't studied the standard
about this, and am just trying to apply common sense.

Your common sense is failing you. If you want to discuss this,
*please* take the time to read the standard. Otherwise you're just
wasting time.

For example:

int n = 10;
int my_vla[n][n];

my_vla is a two-dimensional VLA, each of whose elements is a
one-dimensional VLA. (As always, a two-dimensional array is precisely
an array of arrays.) The elements of my_vla are all the same size,
but since that size is determined at run time they're still VLAs.

The length of a VLA is variable in the sense that it's determined at
run time, but the length of a given VLA object *cannot* change during
its lifetime.

Somewhat off-topic:

Some other languages (I'm thinking of Ada in particular) allow
arbitrary expressions as array bounds. An expression used as an array
bound is evaluated where the type or object is declared; an array's
size cannot chane after it's been created. It's very much like the
way C99 works, except that there's no language-level distinction
between constant-length arrays and variable-length arrays. There are
no particular restrictions, because there's no need for any particular
restrictions.
 
F

Flash Gordon

CBFalconer wrote, On 20/09/07 14:39:
I think we are talking about different things. As far as I am
concerned once the various 'component' VLAs have been constituted,
they have to be the same size, and thus are no longer VLAs. Now
they can be arrayed. I certainly haven't studied the standard
about this, and am just trying to apply common sense.

I can't see anything in the standard that suggests it stops being a VLA
after it has been constituted. The fact the standard talks about
pointers to VLAs actually implies to me that what is declared as a VLA
is a VLA and remains a VLA in terms of type for as long as it exists.
This also makes sense to me because it means the type does not suddenly
change.
 
K

Keith Thompson

Keith Thompson said:
As far as I can tell, VLAs of VLAs are permitted.
[...]

But VLAs, or objects containing VLAs, cannot be members of structs or
unions.
 
P

Peter 'Shaggy' Haywood

Groovy hepcat Charlie Gordon was jivin' in comp.lang.c on Tue, 18 Sep
2007 9:36 pm. It's a cool scene! Dig it.
Richard Bos said:
Martin Wells said:
Someone posted the following excerpt recently in relation to the
sizeof operator:

6.5.3.4p2: "... If the type of the operand is a variable
length array type, the operand is evaluated; otherwise,
the operand is not evaluated and the result is an
integer constant."

The first thing that occured to me was that nothing happens when you
evaluate a VLA.

Consider an expression whose type is a VLA, but whose evaluation
involves side effects. For example, given

size_t n=some_expression();
char arr[14][n]
size_t i=0;

the operation

sizeof (arr[i++])

would return the size of the VLA (which should be n), _and_ increment
i. This is unfortunate, because had the declaration of n been

#define n 93

the very same code would have returned the size of the _non_-VLA (to
wit, 93), and _not_ incremented i.

The moral? Never include side-effects in the operands to sizeof, so
that surprise is minimised.

Actually the moral should be that the Standard has a defect.
Evaluating the argument in not needed to determine the size of the VLA
object, so why should it be mandated ?

Actually, a VLA operand may need to be evaluated since the size is not
hard-wired and may not even be known to the compiler. For example, the
size may be determined by user input. An implementation may somehow
store the size of the VLA with the VLA. It would have to evaluate the
VLA in order to fetch the size information.
Conversely, if the argument is a VLA-type, some form of evaluation
would be necessary, but we would have to define the meaning of
"evaluating a VLA-type."

It is perfectly clear what evaluation means: determining the value of
(the expression), performing side effects and evaluating all
sub-expressions.
An example of this is:

int function();

sizeof(char[function()]);

But then it wouldn't be much of a problem is such an expression was
left as invoking undefined behaviour.

It wouldn't? How odd!
 
K

Keith Thompson

Peter 'Shaggy' Haywood said:
Groovy hepcat Charlie Gordon was jivin' in comp.lang.c on Tue, 18 Sep
2007 9:36 pm. It's a cool scene! Dig it. [...]
Actually the moral should be that the Standard has a defect.
Evaluating the argument in not needed to determine the size of the VLA
object, so why should it be mandated ?

Actually, a VLA operand may need to be evaluated since the size is not
hard-wired and may not even be known to the compiler. For example, the
size may be determined by user input. An implementation may somehow
store the size of the VLA with the VLA. It would have to evaluate the
VLA in order to fetch the size information.

If the operand is an expression, I don't believe it's ever necessary
to evaluate the expression itself in order to determine the size of
the expression (i.e., the size of its type). The type of an
expression is determined at compilation time, even if that type is
variably-modified.

For example, given 'int vla[n];', determining 'sizeof vla' requires
knowing the value of 'n' (actually, the value that 'n' had when the
declaration was processed at run time), but it *doesn't* require
evaluating 'vla' itself. Evaluating 'vla' (in this context, in which
it's not converted to a pointer) would involve evaluating each of its
elements to determine their current values. This is not necessary, or
even useful, in determining 'sizeof vla'.
It is perfectly clear what evaluation means: determining the value of
(the expression), performing side effects and evaluating all
sub-expressions.

But the thing being "evaluated" isn't an expression; it's a type. As
far as I know, the standard doesn't talk about evaluating types,
except indirectly in this one case. It would be easy enough to
define; it requires evaluating each full expression that appears
within the type-name. (We need to specify full expressions, not each
subexpression, because a subexpression could be a
non-variably-modified argument to another sizeof operator.)

[...]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,539
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top