By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,112 Members | 1,601 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,112 IT Pros & Developers. It's quick & easy.

Redundant statement in the Standard?

P: n/a

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. I mean what's the following supposed to do?

{
int arr[some_runtime_figure];

arr;
}

So then I tried to think what *other* expressions could be a VLA. My
first thought was a function, but the following won't compile for me
with a C99 compiler, it says C99 doesn't allow to return an array from
a function:

int Func(void)[5]
{
int arr[5] = {0};

return arr;
}

int main(void)
{
sizeof(Func());
}

Then I used even more of my brain and realised that I hard-coded 5
into the function signature so I wouldn't be able to return a VLA
anyway.

So I'm left wondering, what kind of expression is a VLA, but which
also DOES SOMETHING? What was the purpose of adding that little
paragraph to the Standard?

Would it not have been simpler to leave us with the universal "sizeof
doesn't evaluate its operand"?

Martin

Sep 18 '07 #1
Share this Question
Share on Google+
21 Replies


P: n/a
Martin Wells <wa****@eircom.netwrote:
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.

Richard
Sep 18 '07 #2

P: n/a
"Richard Bos" <rl*@hoekstra-uitgeverij.nla écrit dans le message de news:
46*****************@news.xs4all.nl...
Martin Wells <wa****@eircom.netwrote:
>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 ?

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

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.

--
Chqrlie.
Sep 18 '07 #3

P: n/a
Martin Wells <wa****@eircom.netwrote:
>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.
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
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.
No, I don't think that's the case. arr[i++] is not a VLA -- it's
a character hence sizeof would return 1 and there will be no side
effects.

I suppose that valid example is "sizeof(char[n])" where n is not
a constant.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Sep 18 '07 #4

P: n/a
Michal Nazarewicz <mi****@tlen.plwrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Martin Wells <wa****@eircom.netwrote:
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.

No, I don't think that's the case. arr[i++] is not a VLA -- it's
a character hence sizeof would return 1 and there will be no side
effects.
Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
arr[i++][4] would be a char.
I suppose that valid example is "sizeof(char[n])" where n is not
a constant.
That, too, if n has side effects.

Richard
Sep 18 '07 #5

P: n/a
>rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
>>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.
Michal Nazarewicz <mi****@tlen.plwrote:
>No, I don't think that's the case. arr[i++] is not a VLA -- it's
a character hence sizeof would return 1 and there will be no side
effects.
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
arr[i++][4] would be a char.
Oh... sorry. You're right. :)

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Sep 18 '07 #6

P: n/a
Richard Bos wrote:
Michal Nazarewicz <mi****@tlen.plwrote:
.... snip ...
>>
No, I don't think that's the case. arr[i++] is not a VLA -- it's
a character hence sizeof would return 1 and there will be no side
effects.

Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
arr[i++][4] would be a char.
You can't have an array of arrays. You can have an array of
pointers to an array.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com

Sep 19 '07 #7

P: n/a
In article <46***************@yahoo.com>,
CBFalconer <cb********@maineline.netwrote:
>You can't have an array of arrays. You can have an array of
pointers to an array.
int x[3][5];

declares an array of arrays. You can even have an array of VLAs,
though they must all be the same size.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Sep 19 '07 #8

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Richard Bos wrote:
>Michal Nazarewicz <mi****@tlen.plwrote:
... snip ...
>>>
No, I don't think that's the case. arr[i++] is not a VLA -- it's
a character hence sizeof would return 1 and there will be no side
effects.

Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
arr[i++][4] would be a char.

You can't have an array of arrays.
Incorrect, you most certainly can.
You can have an array of
pointers to an array.
Correct (but a pointer to an array is rarely as useful as a pointer to
the first member of an array).

--
Keith Thompson (The_Other_Keith) 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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 19 '07 #9

P: n/a
CBFalconer <cb********@yahoo.comwrote:
Richard Bos wrote:
Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
arr[i++][4] would be a char.

You can't have an array of arrays. You can have an array of
pointers to an array.
From 6.5.2.1:

# 4 EXAMPLE Consider the array object defined by the declaration
# int x[3][5];
# Here x is a 3 ×5 array of ints; more precisely, x is an array of
# three element objects, each of which is an array of five ints.

'tis only a sample, i'faith, but a convincing one at that, marry.

Richard
Sep 19 '07 #10

P: n/a
On Tue, 18 Sep 2007 19:34:43 -0400, CBFalconer wrote:
You can't have an array of arrays. You can have an array of
pointers to an array.
#include <stdio.h>
int main(void)
{
char a[20][20];
char ((*b[20])[20];
printf("%lu %lu\n", (unsigned long)sizeof a,
(unsigned long)sizeof b);
return 0;
}

--
Army1987 (Replace "NOSPAM" with "email")
If you're sending e-mail from a Windows machine, turn off Microsoft's
stupid “Smart Quotes” feature. This is so you'll avoid sprinkling garbage
characters through your mail. -- Eric S. Raymond and Rick Moen

Sep 19 '07 #11

P: n/a
On Sep 19, 11:34 am, CBFalconer <cbfalco...@yahoo.comwrote:
You can't have an array of arrays. You can have an array of
pointers to an array.
Is this the real CBFalconer?
Sep 19 '07 #12

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Richard Bos wrote:
>Michal Nazarewicz <mi****@tlen.plwrote:
... snip ...
>>>
No, I don't think that's the case. arr[i++] is not a VLA -- it's
a character hence sizeof would return 1 and there will be no side
effects.

Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
arr[i++][4] would be a char.

You can't have an array of arrays. You can have an array of
pointers to an array.
What total and utter nonsense. Another example of the c.l.c word games
at their very worst.

int multi[ROWS][COLS];
>
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Sep 19 '07 #13

P: n/a
On Wed, 19 Sep 2007 18:35:50 +0200, Richard wrote:
CBFalconer <cb********@yahoo.comwrites:
>You can't have an array of arrays. You can have an array of pointers
to an array.

What total and utter nonsense. Another example of the c.l.c word games
at their very worst.

int multi[ROWS][COLS];
It doesn't work as a word game. What you declared is an array of arrays.
multi[0], in most contexts, will be converted to a pointer, but that
doesn't mean it is one. The original claim is simply wrong.
Sep 19 '07 #14

P: n/a
Old Wolf <ol*****@inspire.net.nzwrites:
On Sep 19, 11:34 am, CBFalconer <cbfalco...@yahoo.comwrote:
>You can't have an array of arrays. You can have an array of
pointers to an array.

Is this the real CBFalconer?
It would appear to be from the accuracy of his statements.
Sep 19 '07 #15

P: n/a
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
>Richard Bos wrote:
>>Michal Nazarewicz <mi****@tlen.plwrote:
... snip ...
>>>>
No, I don't think that's the case. arr[i++] is not a VLA -- it's
a character hence sizeof would return 1 and there will be no side
effects.

Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
arr[i++][4] would be a char.

You can't have an array of arrays.

Incorrect, you most certainly can.
The original was dealing with an array of VLAs. I omitted the VLA
word in my comment.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 20 '07 #16

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
>CBFalconer <cb********@yahoo.comwrites:
>>Richard Bos wrote:
Michal Nazarewicz <mi****@tlen.plwrote:
... snip ...
>
No, I don't think that's the case. arr[i++] is not a VLA -- it's
a character hence sizeof would return 1 and there will be no side
effects.

Read again. arr is an array of VLAs, so arr[i++] is the i'th VLA.
arr[i++][4] would be a char.

You can't have an array of arrays.

Incorrect, you most certainly can.

The original was dealing with an array of VLAs. I omitted the VLA
word in my comment.
I think you're still mistaken. As far as I can tell, VLAs of VLAs are
permitted.

The following program:

#include <stdio.h>
int main(void)
{
int n = 10;
char arr[n][n];
printf("sizeof arr[0] = %d\n", (int)sizeof arr[0]);
printf("sizeof arr = %d\n", (int)sizeof arr);
return 0;
}

is accepted without complaint by gcc, icc, and Sun's C compiler under
Solaris 10, and produces the output:

sizeof arr[0] = 10
sizeof arr = 100

(which doesn't actually prove anything), and I don't see any such
restriction in C99 6.7.5.2 (which doesn't really prove anything
either; I might have missed something).

It was also accepted without complaint by Comeau's test drive page,
<http://www.comeaucomputing.com/pcgi-bin/compiler.html>, in strict C99
mode (though that page doesn't give you output).

Can you quote any wording from the standard that forbids VLAs of VLAs?

--
Keith Thompson (The_Other_Keith) 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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 20 '07 #17

P: n/a
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
>Keith Thompson wrote:
>>CBFalconer <cb********@yahoo.comwrites:
.... snip ...
>>>>
You can't have an array of arrays.

Incorrect, you most certainly can.

The original was dealing with an array of VLAs. I omitted the VLA
word in my comment.

I think you're still mistaken. As far as I can tell, VLAs of VLAs
are permitted.
I differ. Arrays need to be composed of equal sized objects.
VLAs, by nature, are variable sized objects. You could have an
array of pointers to VLAs, though.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 20 '07 #18

P: n/a
>Keith Thompson wrote:
>>As far as I can tell, VLAs of VLAs are permitted.
(They are, necessarily so.)

In article <46***************@yahoo.com>,
CBFalconer <cb********@maineline.netwrote:
>I differ. Arrays need to be composed of equal sized objects.
VLAs, by nature, are variable sized objects.
This is the tricky part: while VLAs are "variable length arrays",
each *instance* of any given VLA is fixed-size.

VLAs of VLAs are necessary because one of the goals, perhaps even
the primary goal, of VLAs in the first place was to allow C
programmers to write Fortran-like functions with Fortran-like
convenience, e.g.:

/* perform some operation on a matrix of "double" */
void mat_operate(size_t m, size_t n, double mat[m][n]) {
size_t i, j;

for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
... operate on mat[i][j] ...
}

When mat_operate() is called, m and n are variable, but while
mat_operate() operates, m and n remain fixed. The size of the
matrix "mat" is also fixed.

(This remains true even if m and/or n are modified inside mat_operate().
The size is, in effect, "captured" at the point the VLA is created.)

The key sentences in my draft read:

The size of each instance of a variable length array type
does not change during its lifetime.

and (in part):

... the size of the variable length array type does not change
if the value of n is subsequently changed.
>You could have an array of pointers to VLAs, though.
You can indeed have this, as well. You can also have a VLA of
pointers to VLAs, and so on.

The compile-time compatibility rules for pointers to VLAs are
quite relaxed, with the effect at runtime being undefined if the
sizes of the variably-modified types do not match:

void f(size_t n, double square_mat[n][n]) {
double (*p)[rand()]; /* bad idea, for illustration only */

p = square_mat; /* not a compile-time error */
...
}

The effect is undefined unless n happens to be equal to the
value rand() returns. In practice, in a real C compiler, if
rand() returns a number that does not match n, p[0][j] "works
right" but p[i][j] misbehaves: If we were to capture the
number that came out of the rand() call, e.g., via:

size_t x;
double (*p)[x = rand()];

instead, then p[i][j] is roughly equivalent to mat[0][i * x + j]
as long as no subscript checking occurs. (Of course, because of
the undefined behavior, the compiler can make various assumptions
and optimize this particular weirdness into *other* weirdness.
For instance, it might make the assumption that x must necessarily
equal n, hence remove x from the runtime image and use the saved
n -- so that p[i][j] accesses mat[i][j] after all!)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Sep 20 '07 #19

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
>CBFalconer <cb********@yahoo.comwrites:
>>Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
... snip ...
>>>>>
You can't have an array of arrays.

Incorrect, you most certainly can.

The original was dealing with an array of VLAs. I omitted the VLA
word in my comment.

I think you're still mistaken. As far as I can tell, VLAs of VLAs
are permitted.

I differ. Arrays need to be composed of equal sized objects.
VLAs, by nature, are variable sized objects. You could have an
array of pointers to VLAs, though.
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).

--
Keith Thompson (The_Other_Keith) 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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 20 '07 #20

P: n/a
In article <46***************@yahoo.com>,
CBFalconer <cb********@maineline.netwrote:
>I think you're still mistaken. As far as I can tell, VLAs of VLAs
are permitted.
>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
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Sep 20 '07 #21

P: n/a
Keith Thompson <ks***@mib.orgwrites:
[...]
As far as I can tell, VLAs of VLAs are permitted.
[...]

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

--
Keith Thompson (The_Other_Keith) 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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 21 '07 #22

This discussion thread is closed

Replies have been disabled for this discussion.