Topic: reading the standard (was char *p = new char[0]?)
Author: Darin Adler <darin@bentspoon.com>
Date: 2000/01/29 Raw View
In article <3891CE5D.CB8C5975@sun.com>, Steve Clamage
<stephen.clamage@sun.com> wrote:
> The expression
> new char[0] // error
> is not valid, and the compiler must issue a diagnostic message.
I'm planning to report this as a bug to my compiler vendor, and I'm
having a bit of trouble reading the standard so I can explain the
standard's requirement to diagnose this error. I want to distinguish the
standard's requirement for a diagnostic from my personal preference for
an error message.
5.3.4/6 says that, "Every constant-expression in a direct-new-declarator
shall be an integral constant expression (5.19) and evaluate to a
strictly positive value."
Does the "shall" in this case mandate a diagnostic from the compiler if
the expression is not a strictly positive value?
5.3.4/6 goes on to say, "The expression in a direct-new-declarator shall
have integral type (3.9.1) with a non-negative value."
Why in this case does the "shall" not mandate a diagnostic from the
compiler? I know that the expression's value is not known at compile
time, but how does the standard express this difference? Who is
responsible for not violating the "shall"? The programmer, or the
compiler?
-- Darin
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 2000/01/29 Raw View
Darin Adler wrote:
>
> In article <3891CE5D.CB8C5975@sun.com>, Steve Clamage
> <stephen.clamage@sun.com> wrote:
>
> > The expression
> > new char[0] // error
> > is not valid, and the compiler must issue a diagnostic message.
....
> 5.3.4/6 says that, "Every constant-expression in a direct-new-declarator
> shall be an integral constant expression (5.19) and evaluate to a
> strictly positive value."
>
> Does the "shall" in this case mandate a diagnostic from the compiler if
> the expression is not a strictly positive value?
Section 1.4 p2: "... If a program contains a violation of any
diagnosible rule, a conforming implementation shall issue at least one
diagnostic message, ...". If the expression is a constant which can be
evaluated at compile time, the violation of the rule by a value of zero
is diagnosable.
> 5.3.4/6 goes on to say, "The expression in a direct-new-declarator shall
> have integral type (3.9.1) with a non-negative value."
>
> Why in this case does the "shall" not mandate a diagnostic from the
> compiler? I know that the expression's value is not known at compile
> time, but how does the standard express this difference? Who is
By the term "diagnosible". The compiler can't diagnose a problem that
depends upon run-time behavior, so you can't get a compile-time message
for this problem.
> responsible for not violating the "shall"? The programmer, or the
> compiler?
The "shall" describes the content of the code, not the behavior of the
compiler, so meeting it is the responsibility of the programmer. There's
nothing the compiler CAN do, to meet that requirement.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "William H. Bloodworth" <whbloodworth@usa.net>
Date: 2000/01/29 Raw View
On Sat, 29 Jan 2000 06:54:30 CST, Darin Adler <darin@bentspoon.com> wrote:
>
>5.3.4/6 says that, "Every constant-expression in a direct-new-declarator
>shall be an integral constant expression (5.19) and evaluate to a
>strictly positive value."
>
>5.3.4/6 goes on to say, "The expression in a direct-new-declarator shall
>have integral type (3.9.1) with a non-negative value."
There seems to be a minor contradiction in the two above statements. "...strictly
positive.." (to me) means 1 to positive infinity. "...non-negative.." (to me) means
0 to positive infinity. In the context of the question, this is extemely important.
In terms of usability, the following is useless (is it not?).
... = new datatype[0];
Also, Steve Clamage mentioned...
"In this case, you get a non-null pointer to an array with zero elements.
That is, the pointer itself is valid, but you cannot dereference it."
If this is the case, what are the benefits of having a valid non-dereferencable
pointer? IMHO, a non-dereferencable valid pointer...is invalid; therefore this
should not be allowed.
Another point: An array with 0 elements is not an array.
Analogy: A parent with 0 children is not a parent.
If this point holds any water at all, then if you allocate memory for an array of
zero elements from the heap (...new datatype[0]) then should you use 'delete' or
'delete []'? My guess would have to be delete [] simply because new[] was used for
allocation; but my point is still valid...even if my pointer isn't.
William Bloodworth
==========================================================================
= Great Achievement REQUIRES Great Effort.
=
= William H. Bloodworth - whbloodworth@usa."net" - Maxim Group Consultant
==========================================================================
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Ron Natalie <ron@sensor.com>
Date: 2000/01/30 Raw View
Darin Adler wrote:
> 5.3.4/6 says that, "Every constant-expression in a direct-new-declarator
> shall be an integral constant expression (5.19) and evaluate to a
> strictly positive value."
>
> Does the "shall" in this case mandate a diagnostic from the compiler if
> the expression is not a strictly positive value?
Yes.
>
> 5.3.4/6 goes on to say, "The expression in a direct-new-declarator shall
> have integral type (3.9.1) with a non-negative value."
The question I have is that if you flip back a few lines in the file, you'll
see direct-new-declaration defined as:
direct-new-declarator:
[ expression ]
direct-new-declarator [ constant-expression ]
I wonder if the restriction is misworded? Is it because "every constant-expression"
needed to be positive, or just the ones that are syntactically required by the grammar.
That is, the first pair of brackets which match "expression" in the grammar could be
zero even if it were specified as a constant, where all the subsequent ones (which have
to match the constant-expression in the second choice), need to be positive.
It seems goofy that you can do something with an arbitrary expression you can't do with
a constant.
-Ron
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Steve Clamage <stephen.clamage@sun.com>
Date: 2000/01/30 Raw View
On 29 Jan 2000 15:48:14 GMT, "William H. Bloodworth"
<whbloodworth@usa.net> wrote:
>
>On Sat, 29 Jan 2000 06:54:30 CST, Darin Adler <darin@bentspoon.com> wrote:
>
>>
>>5.3.4/6 says that, "Every constant-expression in a direct-new-declarator
>>shall be an integral constant expression (5.19) and evaluate to a
>>strictly positive value."
>>
>>5.3.4/6 goes on to say, "The expression in a direct-new-declarator shall
>>have integral type (3.9.1) with a non-negative value."
>
>There seems to be a minor contradiction in the two above statements. "...strictly
>positive.." (to me) means 1 to positive infinity. "...non-negative.." (to me) means
>0 to positive infinity. In the context of the question, this is extemely important.
No, a constant-expression used for the array element count must be
greater than zero, but a non-constant expression is allowed to be
zero.
>In terms of usability, the following is useless (is it not?).
>
> ... = new datatype[0];
It's invalid.
>
>Also, Steve Clamage mentioned...
> "In this case, you get a non-null pointer to an array with zero elements.
> That is, the pointer itself is valid, but you cannot dereference it."
>
>If this is the case, what are the benefits of having a valid non-dereferencable
>pointer? IMHO, a non-dereferencable valid pointer...is invalid; therefore this
>should not be allowed.
Read the rest of the posting you quoted from. If the array size is
computed from a function parameter or template parameter, you don't
have to write special code to check for zero. A zero-element array is
a useful concept as a limiting case in algorithms.
Consider the validity of array operations given
T* p = new T[n];
Operations involving p[i] are valid for 0<=i<n, and the expression
&p[n] (or p+n) yields a well-defined pointer value that cannot be
dereferenced. If n is zero, nothing changes. Any use of an array of
dynamic size must always ensure i<n.
You could make a case that new T[0] be allowed on that basis, but
you'd still have an inconsistency with
T array[0]; // static or auto array -- error
This declaration is not allowed because zero-sized objects are not
allowed. (But isn't the heap object zero size? No, because it isn't an
object; you get only an address.) It's a judgement call, but allowing
zero-valued expressions in a dynamic array makes code simpler and more
efficient.
>... if you allocate memory for an array of
>zero elements from the heap (...new datatype[0]) then should you use 'delete' or
>'delete []'? My guess would have to be delete []
Of course. If you allocate with array-new, you must deallocate with
array-delete. The same is true for 1-element arrays.
---
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Ron Natalie <ron@sensor.com>
Date: 2000/01/31 Raw View
"Jack J. Woehr" wrote:
>
> Ron Natalie wrote:
>
> > It seems goofy that you can do something with an arbitrary expression you can't do with
>
> Now, how should the compiler diagnose that you have coded an expression that will
> at runtime evaluate to 0 (zero)? Answer: it can't.
Correct, but since we've already kludged the rule to allow a non-constant expression
of zero meaning allocate unique unsized storage, rather than making it undefined
(like the negative values are), why restrict the case of:
new char[0];
>
> Therefore, if
>
> new char [i] (where i == 0 )
>
> were forbidden, a new type of exception would have to be defined by the standard and
> every compliant runtime would have to be prepared to throw it.
>
That's the opposite of what I wanted. I wanted
new char[0]
to be legal.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/01/31 Raw View
Steve Clamage wrote:
>
> On 29 Jan 2000 15:48:14 GMT, "William H. Bloodworth"
> <whbloodworth@usa.net> wrote:
>
> >
> >On Sat, 29 Jan 2000 06:54:30 CST, Darin Adler <darin@bentspoon.com> wrote:
> >
> >>
> >>5.3.4/6 says that, "Every constant-expression in a direct-new-declarator
> >>shall be an integral constant expression (5.19) and evaluate to a
> >>strictly positive value."
> >>
> >>5.3.4/6 goes on to say, "The expression in a direct-new-declarator shall
> >>have integral type (3.9.1) with a non-negative value."
> >
> >There seems to be a minor contradiction in the two above statements. "...strictly
> >positive.." (to me) means 1 to positive infinity. "...non-negative.." (to me) means
> >0 to positive infinity. In the context of the question, this is extemely important.
>
> No, a constant-expression used for the array element count must be
> greater than zero, but a non-constant expression is allowed to be
> zero.
So the first new in the following program is valid, while
the second one is invalid?
What about the third?
int main()
{
int i1 = 0;
int const i2 = 0;
int const& i3 = 0;
delete[] new char[i1]; // not a constant expression
delete[] new char[i2]; // a constant expression
delete[] new char[i3]; // a constant expression?
}
It's IMHO a rather strange rule to make new char[i1] a
well-defined expression, but new char[i2] illegal.
This way making a variable const may break a program even
if the code remains completely const correct.
Note that this is different to (1/i1) vs. (1/i2), since in
that case the code is broken in both cases - it's just
detected at different times.
[...]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Barry Margolin <barmar@bbnplanet.com>
Date: 2000/01/31 Raw View
In article <3895D315.37DE6687@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>I don't agree here. Either allocating zero elements is defined,
>then it should be allowed to do so explizitly without playing
>games. Or it isn't defined, then it shouldn't be defined even
>for non-consrtant expressions.
>
>Note that { int i=0; p = new char[i]; } is allowed and has
>well-defined behaviour. Now, what if you note that i is never
>changed, and therefore make it const? Or, for that matter, you
>note that it is used just once as rvalue, and replace its use
>with its value directly?
When you notice one of these things, you'll also notice that the array p
points to doesn't contain anything, so you should be able to safely remove
it from the program.
The reason for allowing arrays to be allocated dynamically with size 0 is
so that programs don't have to jump through hoops trying to avoid it with
something like:
if (i != 0)
p = new char[i];
else
// hmm, what to do here?
ANSI C waffled on this -- malloc(0) is allowed to return either a null
pointer or a unique pointer. The C++ designers realized that this type of
thing happens all the time in dynamic allocation, and should be handled.
But there didn't seem to be much need for zero-length statically-sized
arrays (although I suppose I could imagine them coming up occasionally if
the size is from a #define'd constant that might be generated by something
like autoconf).
--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Jack J. Woehr" <jwoehr@ibm.net>
Date: 2000/02/01 Raw View
Ron Natalie wrote:
> It seems goofy that you can do something with an arbitrary expression you can't do with
Now, how should the compiler diagnose that you have coded an expression that will
at runtime evaluate to 0 (zero)? Answer: it can't.
Therefore, if
new char [i] (where i == 0 )
were forbidden, a new type of exception would have to be defined by the standard and
every compliant runtime would have to be prepared to throw it.
Seems more sensible the way the standard did it.
--
Jack J. Woehr # Ceterum censeo
PO Box 51, Golden, CO 80402 # in herbas belli
http://www.well.com/~jax/rcfb # ab idem desistamus.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/02/01 Raw View
"Jack J. Woehr" wrote:
>
> Ron Natalie wrote:
>
> > It seems goofy that you can do something with an arbitrary expression you can't do with
>
> Now, how should the compiler diagnose that you have coded an expression that will
> at runtime evaluate to 0 (zero)? Answer: it can't.
>
> Therefore, if
>
> new char [i] (where i == 0 )
>
> were forbidden, a new type of exception would have to be defined by the standard and
> every compliant runtime would have to be prepared to throw it.
No. The standard could have taken the way it used for 1/i:
Writing "1/0" makes the program ill-formed, while doing
"1/i" where i==0 gives undefined behaviour.
Moreover, even if the committee had decided to throw an
exception, they would not have the need to invent a new one:
new char [i] already can throw bad_alloc.
>
> Seems more sensible the way the standard did it.
I don't agree here. Either allocating zero elements is defined,
then it should be allowed to do so explizitly without playing
games. Or it isn't defined, then it shouldn't be defined even
for non-consrtant expressions.
Note that { int i=0; p = new char[i]; } is allowed and has
well-defined behaviour. Now, what if you note that i is never
changed, and therefore make it const? Or, for that matter, you
note that it is used just once as rvalue, and replace its use
with its value directly?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Gene Bushuyev" <gbush@my-deja.com>
Date: 2000/02/01 Raw View
"Christopher Eltschka" <celtschk@physik.tu-muenchen.de> wrote in message
news:3895D315.37DE6687@physik.tu-muenchen.de...
> "Jack J. Woehr" wrote:
[snip]
> > Therefore, if
> >
> > new char [i] (where i == 0 )
> >
> > were forbidden, a new type of exception would have to be defined by the
standard and
> > every compliant runtime would have to be prepared to throw it.
>
> No. The standard could have taken the way it used for 1/i:
> Writing "1/0" makes the program ill-formed, while doing
> "1/i" where i==0 gives undefined behaviour.
>
But this is not a similar case. Division by zero is an error whether at
compile or run-time. And since 1/0 can be diagnosed at compile time there is
no need to delay the error message till the run-time and make it an
undefined behavior. Both expressions 1/0 and 1/i (where i==0) result in
error, so the behavior is consistent. In case of new char[i] (i==0) and new
char[0] the behavior also must be consistent: Standard must either allow
both or outlaw both.
--
Gene Bushuyev
visit us at www.systemc.org
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/02/02 Raw View
Barry Margolin <barmar@bbnplanet.com> writes:
>ANSI C waffled on this -- malloc(0) is allowed to return either a null
>pointer or a unique pointer. The C++ designers realized that this type of
>thing happens all the time in dynamic allocation, and should be handled.
>But there didn't seem to be much need for zero-length statically-sized
>arrays (although I suppose I could imagine them coming up occasionally if
>the size is from a #define'd constant that might be generated by something
>like autoconf).
I think there are a lot of other situations like this in C++
where orthogonality was not valued very highly.
The end result is that the language is very complex,
with a lot of special cases to learn.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 2000/02/02 Raw View
Barry Margolin wrote:
> In article <3895D315.37DE6687@physik.tu-muenchen.de>,
> Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> >Note that { int i=0; p = new char[i]; } is allowed and has
> >well-defined behaviour. Now, what if you note that i is never
> >changed, and therefore make it const? Or, for that matter, you
> >note that it is used just once as rvalue, and replace its use
> >with its value directly?
>
> When you notice one of these things, you'll also notice that the array p
> points to doesn't contain anything, so you should be able to safely remove
> it from the program.
Or you won't notice anything. Maybe because you are looking
else where. Maybe because you are stupid (maybe because you
are a robot).
Anyway that isn't the problem. You may fail to notice it. Or
prove me that you must notice it before the compiler complains.
--
Valentin Bonnard
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: scorp@btinternet.com (Dave Harris)
Date: 2000/02/03 Raw View
barmar@bbnplanet.com (Barry Margolin) wrote:
> But there didn't seem to be much need for zero-length statically-sized
> arrays (although I suppose I could imagine them coming up occasionally
> if the size is from a #define'd constant that might be generated by
> something like autoconf).
I expect they will become more common with templates, too. I've had cases
like:
template <typename T, int size>
class FixedVector {
T data[size];
//...
};
which failed to compile. It was supposed to behave in a similar way to a
std::vector, and a zero-sized vector is allowed. However, cases like this
can always be worked around with:
T data[ (size == 0) ? 1 : size ];
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: zivca@netvision.net.il (Ziv Caspi)
Date: 2000/02/03 Raw View
On 31 Jan 2000 19:23:50 GMT, Barry Margolin <barmar@bbnplanet.com>
wrote:
>But there didn't seem to be much need for zero-length statically-sized
>arrays (although I suppose I could imagine them coming up occasionally if
>the size is from a #define'd constant that might be generated by something
>like autoconf).
Of course there is: it's a common implementation of compile-time
asserts...
---------------------------------------------
Ziv Caspi
zivca@netvision.net.il
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]