Topic: Array of size 0
Author: Gabriel Dos Reis <gdr@cs.tamu.edu>
Date: Sat, 28 Feb 2004 20:07:55 CST Raw View
wizofaus@hotmail.com (Dylan Nicholson) writes:
| > Given that 'T[0]' is ill-formed in the first place, what is expected
| > about 'T[n]' when n has a runtime null value?
| >
| How is T[0] ill-formed? Or do you mean 'T local_array[0];' ?
Yes. That is the compile-time counter part of new T[n] with n == 0.
Try
template<class T>
struct Z { };
int main() { Z<int[0]> z; }
too.
--
Gabriel Dos Reis
gdr@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Michiel.Salters@cmg.nl (Michiel Salters)
Date: Mon, 1 Mar 2004 11:45:57 CST Raw View
Gabriel Dos Reis <gdr@cs.tamu.edu> wrote in message news:<m37jybcq2j.fsf@merlin.cs.tamu.edu>...
> "Andrew Koenig" <ark@acm.org> writes:
>
> | If new is permitted to return zero, then every call to new must have a
> | corresponding test (although it might be possible to combine multiple tests
> | into one).
>
> But, I would not argue for new to return zero :-) I would argue for
> whatever it returns, when it returns, be a dereferenceable value so
> that calls don't have to make the corresponding checks.
What's that got to do with new T[0]? Whatever new T[n] returns,
you can dereference only n Ts in that array, and (new T[n])+n is
a valid expression for a pointer you can't dereference. Adding
an exception so that new T[0] gives you 1 T* you can dereference
doesn't solve any of my problems.
Regards,
--
Michiel Salters
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Gabriel Dos Reis <gdr@cs.tamu.edu>
Date: Mon, 1 Mar 2004 17:13:19 CST Raw View
Michiel.Salters@cmg.nl (Michiel Salters) writes:
| Gabriel Dos Reis <gdr@cs.tamu.edu> wrote in message news:<m37jybcq2j.fsf@merlin.cs.tamu.edu>...
| > "Andrew Koenig" <ark@acm.org> writes:
| >
| > | If new is permitted to return zero, then every call to new must have a
| > | corresponding test (although it might be possible to combine multiple tests
| > | into one).
| >
| > But, I would not argue for new to return zero :-) I would argue for
| > whatever it returns, when it returns, be a dereferenceable value so
| > that calls don't have to make the corresponding checks.
|
| What's that got to do with new T[0]?
The meaning of "T[0]".
| Whatever new T[n] returns,
| you can dereference only n Ts in that array, and (new T[n])+n is
| a valid expression for a pointer you can't dereference. Adding
| an exception so that new T[0] gives you 1 T* you can dereference
| doesn't solve any of my problems.
But, I'm not arguing for new T[0] returns you anything :-)
--
Gabriel Dos Reis
gdr@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: julien.lamy@ircad.u-strasbg.fr (Julien Lamy)
Date: Fri, 20 Feb 2004 17:15:00 +0000 (UTC) Raw View
Hello,
According to paragraph 6 of item 5.3.4 in the Standard, it is legal to
dynamically allocate an array of size 0, i.e.
new int[0]
is legal.
However, as I understand paragraph 1 of item 8.3.4 ("if the cosntant
expression is present, [...] its value shall be greater than zero"), it
is not legal to have
int myArray[0]
What is the rationale behind this difference ?
Thanks in advance,
--
Julien
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: Fri, 20 Feb 2004 19:54:01 +0000 (UTC) Raw View
Julien Lamy wrote:
> Hello,
> According to paragraph 6 of item 5.3.4 in the Standard, it is legal to
> dynamically allocate an array of size 0, i.e.
> new int[0]
> is legal.
> However, as I understand paragraph 1 of item 8.3.4 ("if the cosntant
> expression is present, [...] its value shall be greater than zero"), it
> is not legal to have
> int myArray[0]
> What is the rationale behind this difference ?
> Thanks in advance,
If you could write
int myArray[0];
it would have no use. You could not access any elements. In addition, we say
that C++ has no zero-sized complete objects. We'd have to make a special case
for myArray[0].
C++ currently allows
int myArray[n];
only when n is an integer constant expression. So you know at compile time
whether the array has any elements, and you can take reasonable steps to avoid
trying to create a fixed array with no elements. If nothing else, you could write
int myArray[ n<=0 ? 1 : n ];
Now consider
int* myArray = new int[n];
If n were not allowed to be zero, the runtime system would have to check for
zero elements and generate some kind of runtime error, probably an exception.
The program would have to check specially for zero size or be prepared to deal
with the exception -- perhaps in many places.
If instead the results of the program were undefined, the situation would be
worse. The program would run on some systems, not on others. A defensive
programmer would have to treat n==0 as a disallowed case.
Allowing n to be zero is useful. Functions and algorithms become simpler. You
can process all the elements (if any) of myArray using
for( int i = 0; i < n; ++n ) { ... myArray[i] ... }
You usually won't need special runtime checks for zero size.
Finally, "new int[0]" is not a special case. It is analagous to malloc(0). In
both cases you get a valid pointer that you cannot dereference.
---
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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: julien.lamy@ircad.u-strasbg.fr (Julien Lamy)
Date: Fri, 20 Feb 2004 20:04:50 +0000 (UTC) Raw View
Hello,
According to paragraph 6 of item 5.3.4 in the Standard, it is legal to
dynamically allocate an array of size 0, i.e.
new int[0]
is legal.
However, as I understand paragraph 1 of item 8.3.4 ("if the cosntant
expression is present, [...] its value shall be greater than zero"), it
is not legal to have
int myArray[0]
What is the rationale behind this difference ?
Thanks in advance,
--
Julien
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: do-not-spam-benh@bwsint.com (Ben Hutchings)
Date: Fri, 20 Feb 2004 22:25:16 +0000 (UTC) Raw View
Julien Lamy wrote:
> Hello,
> According to paragraph 6 of item 5.3.4 in the Standard, it is legal to
> dynamically allocate an array of size 0, i.e.
> new int[0]
> is legal.
> However, as I understand paragraph 1 of item 8.3.4 ("if the cosntant
> expression is present, [...] its value shall be greater than zero"), it
> is not legal to have
> int myArray[0]
> What is the rationale behind this difference ?
I don't know what reasons the committee had, and sadly they were
not systematically recorded, but I can certainly see a justification.
If the program does not decide until run-time just how many elements
will be in an array (as in the case of a new-expression) then it is
reasonable that it might sometimes decide that there will be none at
all, and the programmer shouldn't need to make that a special case.
However, if the programmer must decide in advance how many elements
there will be (as in the case of a declaration) then clearly there
is no point in creating an array that will always be empty.
(Some implementations allow declaration of arrays of dimension 0 as an
extension, but the main reason for this is to support another
extension which allows an array at the end of a struct to be treated
as having a larger dimension than it is declared with.)
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Andrew Koenig" <ark@acm.org>
Date: Sat, 21 Feb 2004 13:17:11 CST Raw View
"Steve Clamage" <stephen.clamage@sun.com> wrote in message
news:c15mlg$pdl$1@news1nwk.SFbay.Sun.COM...
> Finally, "new int[0]" is not a special case. It is analagous to malloc(0).
In
> both cases you get a valid pointer that you cannot dereference.
I think that C90 allows malloc(0) to return 0. So you do indeed get a valid
pointer that you cannot dereference, but that pointer might be the same as
the error indication. In other words, the analogy is not quite completely
accurate.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Gabriel Dos Reis <gdr@cs.tamu.edu>
Date: Sun, 22 Feb 2004 12:00:26 CST Raw View
stephen.clamage@sun.com (Steve Clamage) writes:
| Now consider
| int* myArray = new int[n];
| If n were not allowed to be zero, the runtime system would have to
| check for zero elements and generate some kind of runtime error,
| probably an exception. The program would have to check specially for
| zero size or be prepared to deal with the exception -- perhaps in many
| places.
Is that really different from the current behaviour whereby the
new-expression can throw because of shortage of storage and the
program has to check?
--
Gabriel Dos Reis
gdr@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: wizofaus@hotmail.com (Dylan Nicholson)
Date: Sun, 22 Feb 2004 20:50:30 CST Raw View
Gabriel Dos Reis <gdr@cs.tamu.edu> wrote in message news:<m3y8qwp6uy.fsf@merlin.cs.tamu.edu>...
> stephen.clamage@sun.com (Steve Clamage) writes:
>
> | Now consider
> | int* myArray = new int[n];
> | If n were not allowed to be zero, the runtime system would have to
> | check for zero elements and generate some kind of runtime error,
> | probably an exception. The program would have to check specially for
> | zero size or be prepared to deal with the exception -- perhaps in many
> | places.
>
> Is that really different from the current behaviour whereby the
> new-expression can throw because of shortage of storage and the
> program has to check?
>
Well surely one is an 'exception' (and on modern OS-es, it is truly
exceptional for a memory allocation to fail), where the other might be
a usual, expected case. I can you tell it's a definite pain that at
least one popular compiler produces a crash when trying to delete []
the result of new TYPE[0].
Dylan
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Steve Clamage <stephen.clamage@sun.com>
Date: Mon, 23 Feb 2004 11:26:27 CST Raw View
Gabriel Dos Reis wrote:
> stephen.clamage@sun.com (Steve Clamage) writes:
>
> | Now consider
> | int* myArray = new int[n];
> | If n were not allowed to be zero, the runtime system would have to
> | check for zero elements and generate some kind of runtime error,
> | probably an exception. The program would have to check specially for
> | zero size or be prepared to deal with the exception -- perhaps in many
> | places.
>
> Is that really different from the current behaviour whereby the
> new-expression can throw because of shortage of storage and the
> program has to check?
>
On limited-resource computers where you expect allocation to fail, there is
probably little difference. That is, being able to recover from an
out-of-memory situation takes careful design and programming anyway.
But for common applications on desktop or data-center computer systems, a failed
allocation is unusual, and typically there is little you can do to recover. It
is often reasonable to ignore the out-of-memory exception and let the program
exit more-or-less gracefully.
--
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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Gabriel Dos Reis <gdr@cs.tamu.edu>
Date: Mon, 23 Feb 2004 15:54:24 CST Raw View
wizofaus@hotmail.com (Dylan Nicholson) writes:
| Gabriel Dos Reis <gdr@cs.tamu.edu> wrote in message news:<m3y8qwp6uy.fsf@merlin.cs.tamu.edu>...
| > stephen.clamage@sun.com (Steve Clamage) writes:
| >
| > | Now consider
| > | int* myArray = new int[n];
| > | If n were not allowed to be zero, the runtime system would have to
| > | check for zero elements and generate some kind of runtime error,
| > | probably an exception. The program would have to check specially for
| > | zero size or be prepared to deal with the exception -- perhaps in many
| > | places.
| >
| > Is that really different from the current behaviour whereby the
| > new-expression can throw because of shortage of storage and the
| > program has to check?
| >
| Well surely one is an 'exception' (and on modern OS-es, it is truly
| exceptional for a memory allocation to fail),
As a user of a popular OS, I happen to regretfully be a subject of
those unpleasant experiments where the OS over-commits to memory
allocation and later proceeds on killing random processes (including
sometimes "init"). I've seen that happen too often -- in particular
when running another popular browser -- to disagree with the statement
that "it is truly exceptional". Or maybe you're saying that it is not
a modern OS?
| where the other might be a usual, expected case.
Given that 'T[0]' is ill-formed in the first place, what is expected
about 'T[n]' when n has a runtime null value?
| I can you tell it's a definite pain that at
| least one popular compiler produces a crash when trying to delete []
| the result of new TYPE[0].
well, that is another unpleasant story.
--
Gabriel Dos Reis
gdr@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Andrew Koenig" <ark@acm.org>
Date: Mon, 23 Feb 2004 22:47:33 CST Raw View
"Gabriel Dos Reis" <gdr@cs.tamu.edu> wrote in message
news:m3y8qwp6uy.fsf@merlin.cs.tamu.edu...
> stephen.clamage@sun.com (Steve Clamage) writes:
> | Now consider
> | int* myArray = new int[n];
> | If n were not allowed to be zero, the runtime system would have to
> | check for zero elements and generate some kind of runtime error,
> | probably an exception. The program would have to check specially for
> | zero size or be prepared to deal with the exception -- perhaps in many
> | places.
> Is that really different from the current behaviour whereby the
> new-expression can throw because of shortage of storage and the
> program has to check?
Yes it is, because if running out of storage reliably yields an exception,
it is legitimate for programs to deal with those exceptions by ignoring
them. In that case, either the program runs out of memory and terminates
due to an unhandled exception, or it doesn't run out of memory, and
completes normally.
If new is permitted to return zero, then every call to new must have a
corresponding test (although it might be possible to combine multiple tests
into one). Otherwise, when memory is exhausted, the program is likely to
try to use a zero pointer as if it pointed to an object, resulting in
undefined behavior.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: wizofaus@hotmail.com (Dylan Nicholson)
Date: Wed, 25 Feb 2004 11:46:48 CST Raw View
Gabriel Dos Reis <gdr@cs.tamu.edu> wrote in message news:<m3brnqpagi.fsf@merlin.cs.tamu.edu>...
>
> As a user of a popular OS, I happen to regretfully be a subject of
> those unpleasant experiments where the OS over-commits to memory
> allocation and later proceeds on killing random processes (including
> sometimes "init").
Ah, but I'm guessing maybe you can't detect the fact that the OS
overcommits memory from a C++ bad_alloc. Which to me seems an odd OS
design - OS's shouldn't promise more memory than they can deliver (of
course if you've configured your OS to use an infinitely-expanding
page-file, it's impossible to tell the total virtual memory available,
given that you're competing with non-paging disk usage).
>
> Given that 'T[0]' is ill-formed in the first place, what is expected
> about 'T[n]' when n has a runtime null value?
>
How is T[0] ill-formed? Or do you mean 'T local_array[0];' ?
Dylan
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Gabriel Dos Reis <gdr@cs.tamu.edu>
Date: Wed, 25 Feb 2004 11:47:05 CST Raw View
"Andrew Koenig" <ark@acm.org> writes:
| "Gabriel Dos Reis" <gdr@cs.tamu.edu> wrote in message
| news:m3y8qwp6uy.fsf@merlin.cs.tamu.edu...
| > stephen.clamage@sun.com (Steve Clamage) writes:
|
| > | Now consider
| > | int* myArray = new int[n];
| > | If n were not allowed to be zero, the runtime system would have to
| > | check for zero elements and generate some kind of runtime error,
| > | probably an exception. The program would have to check specially for
| > | zero size or be prepared to deal with the exception -- perhaps in many
| > | places.
|
| > Is that really different from the current behaviour whereby the
| > new-expression can throw because of shortage of storage and the
| > program has to check?
|
| Yes it is, because if running out of storage reliably yields an exception,
| it is legitimate for programs to deal with those exceptions by ignoring
| them. In that case, either the program runs out of memory and terminates
| due to an unhandled exception, or it doesn't run out of memory, and
| completes normally.
|
| If new is permitted to return zero, then every call to new must have a
| corresponding test (although it might be possible to combine multiple tests
| into one).
But, I would not argue for new to return zero :-) I would argue for
whatever it returns, when it returns, be a dereferenceable value so
that calls don't have to make the corresponding checks.
--
Gabriel Dos Reis
gdr@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]