tryick use of sizeof again[Explaination Wanted]

?

=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0F

Harald van D)&k said:
Can anyone think of a case where the evaluation of the argument of
sizeof (when it's a VLA) has a visible effect on the behavior of the
program?

#include <stdio.h>
int f(void) {
puts("f is called!");
return 0;
}
int main(void) {
enum { constant_size = 1 };
const int nonconstant_size = 1;

char nonvla[constant_size];
char vla[nonconstant_size];

printf("sizeof (&nonvla)[f()] = %zu\n", sizeof (&nonvla)[f()]);
printf("sizeof (&vla)[f()] = %zu\n", sizeof (&vla)[f()]);

return 0;
}
The type of the operand in both of your sizeof expressions is char, not
a VLA type.

I think you've overlooked the &. The operands to both sizeof operators
have array types.
 
C

christian.bau

This is not the case for the problem at hand. Both C and C++
do not evaluate the expression of a sizeof.

How do you know that C++ doesn't evaluate the expression? Show me
exactly the page and line in the C Standard that tells us that C++
doesn't evaluate the argument of the sizeof operator.

Oh, you can't do that. There is no such statement in the C Standard.
There may be one in the C++ Standard, and I am sure the guys who read
comp.lang.c++ know everything about it, but this is comp.lang.c.
 
F

Flash Gordon

Harald van Dijk wrote, On 15/09/07 22:13:
Keith Thompson wrote, On 15/09/07 20:52:

Can anyone think of a case where the evaluation of the argument of
sizeof (when it's a VLA) has a visible effect on the behavior of the
program?
size_t size=5
int array[++size];

No, sizeof(array) will always return 6 in this case. The array size is
evaluated when the declaration is reached, but not re-evaluated
afterwards.

I meant to say
sizeof array[++size];
Obviously I my brain was disconnected at the time.
 
I

Ian Collins

Harald said:
Harald said:
On Sat, 15 Sep 2007 12:52:39 -0700, Keith Thompson wrote:
Can anyone think of a case where the evaluation of the argument of
sizeof (when it's a VLA) has a visible effect on the behavior of the
program?
#include <stdio.h>
int f(void) {
puts("f is called!");
return 0;
}
int main(void) {
enum { constant_size = 1 };
const int nonconstant_size = 1;

char nonvla[constant_size];
char vla[nonconstant_size];

printf("sizeof (&nonvla)[f()] = %zu\n", sizeof (&nonvla)[f()]);
printf("sizeof (&vla)[f()] = %zu\n", sizeof (&vla)[f()]);

return 0;
}

This should print:

sizeof (&nonvla)[f()] = 1
f is called!
sizeof (&vla)[f()] = 1
Should it?

This is the behaviour mandated by the standard and implemented by the
compiler I'm using. If you believe the standard would have been better if
sizeof on VLAs were specified differently, then I don't necessarily
disagree, but if you believe the standard requires (or allows) any
different output, then could you please explain why?

My thinking was the same as Keith's.

I just tried it with a couple of compilers and got

sizeof (&nonvla)[f()] = 1
sizeof (&vla)[f()] = 1

from both.
 
?

=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0F

Harald said:
Harald van Dijk wrote:
On Sat, 15 Sep 2007 12:52:39 -0700, Keith Thompson wrote:
Can anyone think of a case where the evaluation of the argument of
sizeof (when it's a VLA) has a visible effect on the behavior of the
program?
#include <stdio.h>
int f(void) {
puts("f is called!");
return 0;
}
int main(void) {
enum { constant_size = 1 };
const int nonconstant_size = 1;

char nonvla[constant_size];
char vla[nonconstant_size];

printf("sizeof (&nonvla)[f()] = %zu\n", sizeof (&nonvla)[f()]);
printf("sizeof (&vla)[f()] = %zu\n", sizeof (&vla)[f()]);

return 0;
}

This should print:

sizeof (&nonvla)[f()] = 1
f is called!
sizeof (&vla)[f()] = 1
Should it?

This is the behaviour mandated by the standard and implemented by the
compiler I'm using. If you believe the standard would have been better
if sizeof on VLAs were specified differently, then I don't necessarily
disagree, but if you believe the standard requires (or allows) any
different output, then could you please explain why?

My thinking was the same as Keith's.

That the operand to sizeof is a char? If you change the array length from
1 to 2 you will see the printed size change; if it had type char, it
would remain 1.
I just tried it with a couple of compilers and got

sizeof (&nonvla)[f()] = 1
sizeof (&vla)[f()] = 1

from both.

Which compilers are those? GCC 4.1 doesn't call f. GCC 4.2 and Intel CC
10.0 do.
 
R

rafaelc

How do you know that C++ doesn't evaluate the expression? Show me
exactly the page and line in the C Standard that tells us that C++
doesn't evaluate the argument of the sizeof operator.

Oh, you can't do that. There is no such statement in the C Standard.
There may be one in the C++ Standard, and I am sure the guys who read
comp.lang.c++ know everything about it, but this is comp.lang.c.

We learn by repetition.
We learn by repetition.
We learn by repetition.

"Why be unnecessarily obtuse when the issue is not C++ specific."
"Why be unnecessarily obtuse when the issue is not C++ specific."
"Why be unnecessarily obtuse when the issue is not C++ specific."

See, the guy probably only used "cout" because he found it easier or he didn't
even relise there really is a difference between C and C++. The bad thing here
is not telling the guy that, but it's being overly obnoxious about the whole
thing. Would it be too hard to say something like the following?

"Hey, that cout thing is actually C++. We deal with C here. I can see from your
code that you're struggling with sizeof's argument not being evaluated. I can
tell you that in the C programming language..."

If you don't understand the guy's struggle, simple don't answer the thread. It's
really simple. No need for bashing him, making his life difficult over so
little. Other people realised that and answered him properly and he seemed
to make him satisfied. That's orienting, that's being helpful. Giving him crap
because he had a line that's not standard C is being obtuse.
 
I

Ian Collins

Harald said:
I just tried it with a couple of compilers and got

sizeof (&nonvla)[f()] = 1
sizeof (&vla)[f()] = 1

from both.

Which compilers are those? GCC 4.1 doesn't call f. GCC 4.2 and Intel CC
10.0 do.

gcc 4.0.2 and Sun cc.
 
?

=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0F

Harald van Dijk wrote, On 15/09/07 22:13:
Keith Thompson wrote, On 15/09/07 20:52:

<snip>

Can anyone think of a case where the evaluation of the argument of
sizeof (when it's a VLA) has a visible effect on the behavior of the
program?
size_t size=5
int array[++size];

No, sizeof(array) will always return 6 in this case. The array size is
evaluated when the declaration is reached, but not re-evaluated
afterwards.

I meant to say
sizeof array[++size];
Obviously I my brain was disconnected at the time.

array[++size] is an expression of type int, so ++size will not be
evaluated.
 
P

Peter Nilsson

Harald van D k said:
Ian said:
Harald said:
Keith Thompson wrote:
Can anyone think of a case where the evaluation of the
argument of sizeof (when it's a VLA) has a visible
effect on the behavior of the program?

#include <stdio.h>
int f(void) {
puts("f is called!");
return 0;
}
int main(void) {
enum { constant_size = 1 };
const int nonconstant_size = 1;

char nonvla[constant_size];
char vla[nonconstant_size];

printf("sizeof (&nonvla)[f()] = %zu\n",
sizeof (&nonvla)[f()]);
printf("sizeof (&vla)[f()] = %zu\n",
sizeof (&vla)[f()]);

return 0;
}

This should print:

sizeof (&nonvla)[f()] = 1
f is called!
sizeof (&vla)[f()] = 1

Should it?

This is the behaviour mandated by the standard and
implemented by the compiler I'm using. If you believe
the standard would have been better if sizeof on VLAs
were specified differently, then I don't necessarily
disagree, but if you believe the standard requires (or
allows) any different output, then could you please
explain why?

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

Since you don't apply sizeof to an operand of variable
length array type, I don't see how or why f should be
called.

I believe the evaluation clause in 6.5.3.4p2 is more for
cases like...

sizeof (int [nonconstexpr])

Since pointer arithmetic is required to work on VLAs,
such pointers (including those created by using the name
of a VLA) necessarily carry information about the VLAs
size, either directly or indirectly.

Consider...

#include <stdio.h>
#include <stdlib.h>

int foo()
{
return 1 + rand() % 10;
}

size_t bah(char (*vlap)[*])
{
return sizeof *vlap;
}

int main()
{
int vla[foo()];
printf("%zu\n", bah(&vla));
return 0;
}

The function foo() is only called once. A compiler that
calls foo() twice would be broken.
 
R

Richard Tobin

Keith Thompson said:
Can anyone think of a case where the evaluation of the argument of
sizeof (when it's a VLA) has a visible effect on the behavior of the
program?

Gcc with flags "-std=c99 -pedantic -Wall' thinks the following program
is legal:

#include <stdio.h>

int main(void)
{
int n = 42;
printf("%d\n", (int)sizeof(char [n++]));
printf("%d\n", (int)sizeof(char [n++]));
return 0;
}

and it prints:

42
43

-- Richard
 
K

Keith Thompson

Harald van D©¦k said:
Harald van D)&k said:
On Sat, 15 Sep 2007 12:52:39 -0700, Keith Thompson wrote: [...]
Can anyone think of a case where the evaluation of the argument of
sizeof (when it's a VLA) has a visible effect on the behavior of the
program?

#include <stdio.h>
int f(void) {
puts("f is called!");
return 0;
}
int main(void) {
enum { constant_size = 1 };
const int nonconstant_size = 1;

char nonvla[constant_size];
char vla[nonconstant_size];

printf("sizeof (&nonvla)[f()] = %zu\n", sizeof (&nonvla)[f()]);
printf("sizeof (&vla)[f()] = %zu\n", sizeof (&vla)[f()]);

return 0;
}
The type of the operand in both of your sizeof expressions is char, not
a VLA type.

I think you've overlooked the &. The operands to both sizeof operators
have array types.

You're right (and gcc gets this wrong).
 
F

Flash Gordon

Harald van Dijk wrote, On 16/09/07 00:52:
Harald van Dijk wrote, On 15/09/07 22:13:
52:

<snip>

Can anyone think of a case where the evaluation of the argument of
sizeof (when it's a VLA) has a visible effect on the behavior of the
program?
size_t size=5
int array[++size];
No, sizeof(array) will always return 6 in this case. The array size is
evaluated when the declaration is reached, but not re-evaluated
afterwards.
I meant to say
sizeof array[++size];
Obviously I my brain was disconnected at the time.

array[++size] is an expression of type int, so ++size will not be
evaluated.

I've definitely been working too many hours this week. Normal service
will be restored once I've taken my brain out and washed all the rubbish
out of it.
 
C

Charlie Gordon

Richard Tobin said:
Keith Thompson said:
Can anyone think of a case where the evaluation of the argument of
sizeof (when it's a VLA) has a visible effect on the behavior of the
program?

Gcc with flags "-std=c99 -pedantic -Wall' thinks the following program
is legal:

#include <stdio.h>

int main(void)
{
int n = 42;
printf("%d\n", (int)sizeof(char [n++]));
printf("%d\n", (int)sizeof(char [n++]));
return 0;
}

and it prints:

42
43

While it seems logic to do so, the language of the standard is not clear:

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

What if the type of char[n++] ?
How can we evaluate char[n++] ?

char [n++] *is* a type, it does not *have* a type.

I don't think the language of the standard correctly specifies what should
be the behaviour of such code.

A more compelling example would be

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
if (argc > 1) {
int n = strtol(argv[1], NULL, 0);
int matrix[n][n];
int i = 1;

printf("i=%d, n=%d\n", i, n);
printf ("sizeof(matrix) = %zd\n", sizeof(matrix));
printf ("sizeof(matrix[i++]) = %zd\n", sizeof(matrix[i++]));
printf("i=%d\n", i);

printf ("sizeof(char[i++]) = %zd\n", sizeof(char[i++]));
printf("i=%d\n", i);
}
return 0;
}

with gcc upto version 4.1.3, I get what I interpret as non conforming
behaviour:

$ ./vla 2
i=1, n=2
sizeof(matrix) = 16
sizeof(matrix[i++]) = 8
i=1
sizeof(char[i++]) = 1
i=2

I think we have a defect here: the argument to sizeof should be evaluated is
it *is* a variable length array type, not if it is an expression whois type
can be determined from static analysis.
 
R

Richard Bos

CBFalconer said:
Why did you snip away the expression that triggered the query?

Because it's immaterial to his point, which is that _all_ such
expressions _may_ be different in C++, and only comp.lang.c++ can tell
you for certain.
I.e:


which has the same answer in C and C++ (I think),

Precisely. _You think_. comp.lang.c++ would _know_.

Richard
 
C

CBFalconer

Richard said:
.... snip ...

Precisely. _You think_. comp.lang.c++ would _know_.

No, they wouldn't. In general their knowledge of C is probably
similar to my knowledge of C++ - i.e. fair, but not comprehensive.
 
K

Keith Thompson

Precisely. _You think_. comp.lang.c++ would _know_.

You're assuming that the folks in comp.lang.c++ know enough about C to
be sure about such things. (That may be an accurate assumption.)
 
F

Flash Gordon

CBFalconer wrote, On 17/09/07 08:29:
No, they wouldn't. In general their knowledge of C is probably
similar to my knowledge of C++ - i.e. fair, but not comprehensive.

I think the point is they would _know_ the behaviour in C++. After all,
the original code _was_ C++ because it used C++ specific features on
another line.
 
K

Kelsey Bjarnason

[snips]

Yeah right sizeof('a') == 1 in C++ and sizeof('a') == sizeof(int) in C (how
stupid and counter-intuitive!)

There were legitimate reasons for this, however.
someone knowing absolutely everything about C but nothing about C++ would
fit my definition of obtuse perfectly.

Actually, that'd fit my definition of "C programmer who hasn't learned C++."
 
C

CBFalconer

Flash said:
CBFalconer wrote, On 17/09/07 08:29:

I think the point is they would _know_ the behaviour in C++. After
all, the original code _was_ C++ because it used C++ specific
features on another line.

Which (I think) is just what I said. An answer requires knowledge
of both systems.
 
C

CBFalconer

Kelsey said:
On Sat, 15 Sep 2007 00:31:53 +0200, Charlie Gordon wrote:

[snips]
Yeah right sizeof('a') == 1 in C++ and sizeof('a') == sizeof(int)
in C (how stupid and counter-intuitive!)

There were legitimate reasons for this, however.
someone knowing absolutely everything about C but nothing about
C++ would fit my definition of obtuse perfectly.

Actually, that'd fit my definition of "C programmer who hasn't
learned C++."

LOL. Accurate.
 

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,813
Messages
2,569,696
Members
45,486
Latest member
Deanna5597

Latest Threads

Top