473,396 Members | 1,813 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Redundant statement in the Standard?


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
21 1366
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
"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
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
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
>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
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
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
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
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
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
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
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
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
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
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
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
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
>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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: max(01)* | last post by:
hi everybody. suppose that code-1.py imports code-2.py and code-3.py (because it uses names from both), and that code-2.py imports code-3.py. if python were c, code-1.c should only *include*...
5
by: gordy | last post by:
edit: this came out longer than I thought, any comments about anything here is greatly appreciated. thank you for reading My system stores millions of records, each with fields like firstname,...
99
by: Mikhail Teterin | last post by:
Hello! Consider the following simple accessor function: typedef struct { int i; char name; } MY_TYPE; const char *
14
by: Ian Pilcher | last post by:
It's pretty common to see declarations such as: static volatile sig_atomic_t caught_signal = 0; C99 defines sig_atomic_t as a "... (possibly volatile-qualified) integer type of an object that...
40
by: Neo The One | last post by:
I think C# is forcing us to write more code by enforcing a rule that can be summarized as 'A local variable must be assgined *explicitly* before reading its value.' If you are interested in what...
6
by: Fir5tSight | last post by:
Hi All, I have a "SELECT" statement in a stored procedure that looks like the follows: ...
1
by: lynux | last post by:
Hye, I'm quite new in postgres.I have 2 problems that i do not how to solve. Hope somebody can help me. 1. Although i put my zone field is unique, postgres sometimes redundant my data...
0
by: alan4cast | last post by:
I'm not a really new programmer, but I'm still working on learning all of the .net things that I should know. So when I came across this one, I started to dig into it so see if I could figure it...
18
by: dspfun | last post by:
Hi! The words "expression" and "statement" are often used in C99 and C- textbooks, however, I am not sure of the clear defintion of these words with respect to C. Can somebody provide a sharp...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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,...
0
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.