What will happen when the size of a local variable length array turns out to be 0 (zero)?

X

Xiangliang Meng

Hi.

void setValue(int n)
{
int size = getValueLength();
int buffer_p[size];

if (buffer_p)
{
....
}
}
When the local variable size is 0, will buffer_p be a null pointer? I doubt
it.

What will happen when the size of a local variable length array turns out to
be 0 (zero)? Is it an undefined behavior? Or an implementation-defined one?

Thank you.

Best Regards,

Xiangliang Meng
 
V

Victor Bazarov

Xiangliang Meng said:
void setValue(int n)
{
int size = getValueLength();
int buffer_p[size];

This is not C++.
if (buffer_p)
{
....
}
}
When the local variable size is 0, will buffer_p be a null pointer? I doubt
it.

It won't compile.
What will happen when the size of a local variable length array turns out to
be 0 (zero)? Is it an undefined behavior? Or an implementation-defined
one?

It's a semantic error. The expression in brackets has to be
a compile-time constant.

Victor
 
J

Jowtte

Consider this code:

int testAlloc()
{
int size = 0;
int* buffer = new int [ size ];
int* buffer2 = new int [ 1 ];
...
}

It does allocate memory for buffer, yet I don't know how large it is.

Using my compiler, before "new" operating, buffer = buffer2 = 0xcccccccc
and after "new", buffer = 0x0x00430060, buffer2 = 0x00430030

I don't know why.

Victor Bazarov said:
Xiangliang Meng said:
void setValue(int n)
{
int size = getValueLength();
int buffer_p[size];

This is not C++.
if (buffer_p)
{
....
}
}
When the local variable size is 0, will buffer_p be a null pointer? I doubt
it.

It won't compile.
What will happen when the size of a local variable length array turns
out
to
be 0 (zero)? Is it an undefined behavior? Or an implementation-defined
one?

It's a semantic error. The expression in brackets has to be
a compile-time constant.

Victor
 
D

Dave Townsend

0xcccccc is just MSVC++ fill pattern for uninitialized variables
when you run in debug mode. If you look closely, you'll see size
has the same pattern before its initialized.


Jowtte said:
Consider this code:

int testAlloc()
{
int size = 0;
int* buffer = new int [ size ];
int* buffer2 = new int [ 1 ];
...
}

It does allocate memory for buffer, yet I don't know how large it is.

Using my compiler, before "new" operating, buffer = buffer2 = 0xcccccccc
and after "new", buffer = 0x0x00430060, buffer2 = 0x00430030

I don't know why.

Victor Bazarov said:
Xiangliang Meng said:
void setValue(int n)
{
int size = getValueLength();
int buffer_p[size];

This is not C++.
if (buffer_p)
{
....
}
}
When the local variable size is 0, will buffer_p be a null pointer? I doubt
it.

It won't compile.
What will happen when the size of a local variable length array turns
out
to
be 0 (zero)? Is it an undefined behavior? Or an implementation-defined
one?

It's a semantic error. The expression in brackets has to be
a compile-time constant.

Victor
 
T

those who know me have no need of my name

[fu-t set]

in comp.lang.c i read:

hello. please do not cross-post between comp.lang.c and comp.lang.c++
unless you are reasonably certain the question and/or answer can or will
apply equally well to both languages -- not the case here.
int size = getValueLength();
int buffer_p[size];

this is not valid c++. as such the remainder of this response is c
oriented, and is the reason behind the followup-to header i've used.

in c you would have a vla with no usable elements.
if (buffer_p)
When the local variable size is 0, will buffer_p be a null pointer? I doubt
it.

buffer_p is not a pointer, ever, in any way. when you use buffer_p the
value it yields is a pointer (to the first element), but buffer_p itself
remains an array. when the vla is zero sized buffer_p will not yield a
null pointer value, it will have a distinct non-null address.
What will happen when the size of a local variable length array turns out to
be 0 (zero)? Is it an undefined behavior? Or an implementation-defined one?

declaring an array with a constant expression that evaluates to zero is a
constraint violation, but it is valid and well defined for a vla. of
course none of the elements may be accessed -- attempting to do so has
undefined behavior -- so, about the only things you can do involve the &
and sizeof operators.
 
D

David Harmon

On 10 Jun 2004 04:54:05 GMT in comp.lang.c++, Barry Schwarz
Xiangliang Meng said:
void setValue(int n)
{
int size = getValueLength();
int buffer_p[size];

This is not C++.

No, it's perfectly good C99.

What part of "This is not C++" do you not understand.
As long as you are crossposting your answers to comp.lang.c++,
please confine yourself to standard conforming C++ code.
 
R

Richard Bos

Xiangliang Meng said:
void setValue(int n)
{
int size = getValueLength();
int buffer_p[size];

if (buffer_p)
{
....
}
}
When the local variable size is 0, will buffer_p be a null pointer? I doubt
it.

Please do not cross-post questions like these to comp.lang.c and
comp.lang.c++. C and C++ are different languages, and some of the most
fundamental differences can be found in the area of memory allocation
and the type system. Therefore, the answer may well be different
depending on whether you're writing C or C++. I'll answer this question
presuming you want a C answer, and have set follow-ups accordingly.


Paragraph 6.7.5.2 of the C99 Standard says, amongst other things,

# If the size expression is not a constant expression, and it is
# evaluated at program execution time, it shall evaluate to a
# value greater than zero.

Since this appears outside the "constraints" part of that paragraph,
violating it causes undefined behaviour. IOW, if, in your code, size
turns out to be 0, the array declaration is allowed to result in
anything at all. A null pointer is allowed; an array of one member is
allowed; crashing the program is allowed, too.

Richard
 
R

Richard Bos

David Harmon said:
int size = getValueLength();
int buffer_p[size];

This is not C++.

No, it's perfectly good C99.

What part of "This is not C++" do you not understand.
As long as you are crossposting your answers to comp.lang.c++,
please confine yourself to standard conforming C++ code.

Since it is also cross-posted to comp.lang.c, please confine yourself to
Standard-conforming C code.

The moral of this post? Don't cross-post between c.l.c and c.l.c++;
you'll only make posters cross.

Richard
 
G

Grumble

David said:
On 10 Jun 2004 04:54:05 GMT in comp.lang.c++, Barry Schwarz
void setValue(int n)
{
int size = getValueLength();
int buffer_p[size];

This is not C++.

No, it's perfectly good C99.

What part of "This is not C++" do you not understand. As long as you
are crossposting your answers to comp.lang.c++, please confine
yourself to standard conforming C++ code.

I think Barry meant:

"No [it is not C++ indeed], [however] it's perfectly good C99."
 
X

Xiangliang Meng

Hi, all.

It's all my fault putting this both in comp.lang.c and comp.lang.c++. Very
sorry for that.

This fragment code is extracted out from a class member function. In
addition, those codes are compiled by gcc. I'm not familar with C++
standard. As far as I know, the variable length array is introduced in C99,
but I do NOT know whether C++ has this. So I cross-posted it.

It should be
void Componet::setValue(int n)
{
int size = getValueLength();
int buffer_p[size];

if (buffer_p)
{
...
}
}

ATTENTION:
============================================================================
===================
Any one who answers my question, please post ONLY in comp.lang.c from now
on. Thank all of you.
============================================================================
===================

Best Regards,

Xiangliang Meng
 
R

Richard Bos

Xiangliang Meng said:
It's all my fault putting this both in comp.lang.c and comp.lang.c++. Very
sorry for that.

This fragment code is extracted out from a class member function.

That should have told you; C does not have, never has had, and by the
grace of the Committee never will have classes.
It should be
void Componet::setValue(int n)

This is _not_ C. Whether it is valid C++ I do not know, but it is not C
- neither C89 nor C99 nor even Ganuck.
{
int size = getValueLength();
int buffer_p[size];

Therefore, talking about this code as if it is guaranteed to have C99
semantics is misleading.
Any one who answers my question, please post ONLY in comp.lang.c from now
on. Thank all of you.

No, do _not_ answer this in comp.lang.c. Whatever it is, it is some kind
of (possibly Ganuck++-specific) C++. It is certainly not C, therefore it
does not belong in comp.lang.c. Follow-ups set the other way.

Richard

[ Learn to snip, btw. ]
 
A

Alf P. Steinbach

* Xiangliang Meng:
It's all my fault putting this both in comp.lang.c and comp.lang.c++. Very
sorry for that.

This fragment code is extracted out from a class member function. In
addition, those codes are compiled by gcc. I'm not familar with C++
standard. As far as I know, the variable length array is introduced in C99,
but I do NOT know whether C++ has this. So I cross-posted it.

It should be
void Componet::setValue(int n)
{
int size = getValueLength();
int buffer_p[size];

if (buffer_p)
{
...
}
}

Above you're using a C99 feature in a C++ program.

C99 does not have classes, and C++ does not have variable length arrays.

So the mix of the two features is something not allowed in either
language.

However, in C++ you can use the standard library's vector class to
achieve the same effect, as follows:

void Componet::setValue( int n )
{
int size = getValueLength();
std::vector<int> buffer( size );
...
}

and in C99 you can rewrite the thing as e.g.

void Componet_setvalue( Component* self, int n )
{
int size = self->getValueLength();
if( size == 0 ) { return; }
int buffer[size];
...
}

But first of all you need to decide which language you're using.
 
J

Jorge Rivera

Jowtte said:
Consider this code:

int testAlloc()
{
int size = 0;
int* buffer = new int [ size ];
int* buffer2 = new int [ 1 ];
...
}

It does allocate memory for buffer, yet I don't know how large it is.

Using my compiler, before "new" operating, buffer = buffer2 = 0xcccccccc
and after "new", buffer = 0x0x00430060, buffer2 = 0x00430030

I don't know why.

I think the standard dictates that calls to new with size 0 will return
a valid pointer, therefore this is well-defined behavior (although what
really happens is likely to be an allocation of 1, or sizeof(T);
 
B

Branimir Maksimovic

..........................

This is g++ specific extension in this case.
If size is 0 then nothing will happen, though you can't access
array elements 'cause there are none.
In order to avoid this situation use this:
void Componet::setValue(int n)
{
int size = getValueLength();
int buffer_p[size];
//> if (buffer_p)
// buffer_p would be always non null pointer
if(sizeof buffer_p) // sizeof would be evaluated in run time
{
...
}
}

Finally, I have question for C newsgroup.
Given,

void func(size_t size)
{
assert(size != 0);
int buf[size];
size_t tmp= sizeof (buf);
}

what would be result of sizeof? Some compile time constant
or run time evaluated value?

Greetings, Bane.
 
C

CBFalconer

Jorge said:
Jowtte said:
int testAlloc()
{
int size = 0;
int* buffer = new int [ size ];
int* buffer2 = new int [ 1 ];
...
}

It does allocate memory for buffer, yet I don't know how large it is.

Using my compiler, before "new" operating, buffer = buffer2 = 0xcccccccc
and after "new", buffer = 0x0x00430060, buffer2 = 0x00430030

I don't know why.

I think the standard dictates that calls to new with size 0 will return
a valid pointer, therefore this is well-defined behavior (although what
really happens is likely to be an allocation of 1, or sizeof(T);

This is not valid C code, and is OT in c.l.c. F'ups set.
 
C

CBFalconer

Xiangliang said:
It's all my fault putting this both in comp.lang.c and
comp.lang.c++. Very sorry for that.
.... snip ...

ATTENTION:
===================
Any one who answers my question, please post ONLY in comp.lang.c
from now on. Thank all of you.

You have a simple mechanism available for that, which should have
been applied to the original post. Set followups.
 
J

Jack Klein

.........................

This is g++ specific extension in this case.
If size is 0 then nothing will happen, though you can't access
array elements 'cause there are none.
In order to avoid this situation use this:
void Componet::setValue(int n)
{
int size = getValueLength();
int buffer_p[size];
//> if (buffer_p)
// buffer_p would be always non null pointer
if(sizeof buffer_p) // sizeof would be evaluated in run time
{
...
}
}

Finally, I have question for C newsgroup.
Given,

void func(size_t size)
{
assert(size != 0);
int buf[size];
size_t tmp= sizeof (buf);
}

what would be result of sizeof? Some compile time constant
or run time evaluated value?

Greetings, Bane.

The sizeof operator in C99 is evaluated at run time when it is applied
to a VLA. In all other cases it is the same as before, a compile time
operation that yields a compile time constant.
 

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

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top