Thread View: comp.std.c++
5 messages
5 total messages
Started by Marek MAKOWSKI
Thu, 01 Feb 1996 15:49
new T[0] and sizeof(T)
Author: Marek MAKOWSKI
Date: Thu, 01 Feb 1996 15:49
Date: Thu, 01 Feb 1996 15:49
57 lines
2795 bytes
2795 bytes
I would like to ask for comments on three easy questions illustrated
by the following piece of code:
template <class I, class T>
void mVect<I,T>::resize(I new_size) {
T *old = v;
v = new T[new_size]; // T *v is a private member of mVect
int size_of_elem = sizeof(T); // <--- question 3
//
// do something
//
delete[] old; // <--- questions 1 & 2
}
I have the following questions:
1. Is it absolutely robust and portable to delete[] old, even
if a previous call was for new_size == 0 (or if v was allocated
by the ctor for the size == 0) ?
In other words: is it guaranteed that:
(v = new T[0]) == 0;
2. Is it correct to assume that no destructor is called by this statement
if old was set as: old = new T[0] ??
3. Is there any risk involved in using sizeof(T) in this statement ?
I used to be sure that the answers are:
1. Yes
2. Yes
3. No
However, I have recently started to port an application developed
with SunPro (previously ported to Borland and checked with the
Bounds-Checker32).
The Watcom code blows-up on the delete[] statement (if a previous
call was for new_size == 0) and gives a warning whenever it sees the
sizeof(T).
If the answer for quaestions 1 and 2 is negative then I would like to
know the reason why the standard does not require new to return 0
for zero_size array of objects.
This would work nicely with the delete guaranteed to be safe for
the 0 argument.
If there is a good reason for allowing new to return "anything" in such
situations then one should add to every ctor setting a ptr to 0
(which indeed made the Watcom version of my application running).
Thanks in advance for your time.
Marek
--
Marek Makowski | Email: marek@iiasa.ac.at
International Institute | Phone: (+43-2236) 807.561
for Applied Systems Analysis | Fax: (+43-2236) 71.313
A-2361 Laxenburg, Austria | Web: http://www.iiasa.ac.at
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: new T[0] and sizeof(T)
Author: Steve Clamage
Date: Fri, 02 Feb 1996 01:38
Date: Fri, 02 Feb 1996 01:38
62 lines
3298 bytes
3298 bytes
In article 4676@iiasa.ac.at, marek@iiasa.ac.at (Marek MAKOWSKI) writes:
>I would like to ask for comments on three easy questions illustrated
>by the following piece of code:
>
>template <class I, class T>
>void mVect<I,T>::resize(I new_size) {
> T *old = v;
> v = new T[new_size]; // T *v is a private member of mVect
> int size_of_elem = sizeof(T); // <--- question 3
> //
> // do something
> //
> delete[] old; // <--- questions 1 & 2
>}
>
>I have the following questions:
>1. Is it absolutely robust and portable to delete[] old, even
> if a previous call was for new_size == 0 (or if v was allocated
> by the ctor for the size == 0) ?
If you allocate an object with new[], you delete it with delete[]. In
addition, it is always safe to delete a null pointer.
> In other words: is it guaranteed that:
> (v = new T[0]) == 0;
No. The result of 'new' is never a null pointer (unless the allocation fails
and you are using a pre-exception or "nothrow" version of new). A request of
zero size results in a pointer value distinct from all other pointer values
in the program. So if you write
T* t1 = new T[count];
T* t2 = new T[count];
and if the allocations succeed, it must be true that
( t1 != 0 && t1 != t2 && t2 != 0 )
even if count is zero. The expression "new T[0]" is invalid, but if you
use a non-const expression for the count, it is OK if the value is zero.
Since you have requested zero objects, you cannot dereference the resulting
pointer -- it might not point at usable storage. But since you acquired the
pointer value from "new" you can (and should) pass it to "delete".
>2. Is it correct to assume that no destructor is called by this statement
> if old was set as: old = new T[0] ??
As noted above, "new T[0]" isn't valid, but if you ask for zero objects,
no objects are created. When you delete the array, no destructors
should be called. I can believe that a compiler might get some part of
these requirements wrong, since this sort of thing hardly ever happens and
bugs might slip through testing.
>3. Is there any risk involved in using sizeof(T) in this statement ?
If T is a completely-defined type, you can always ask for sizeof(T); its
value is a compile-time constant. I'm afraid I don't understand this
question.
---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is
in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]
Re: new T[0] and sizeof(T)
Author: Fergus Henderson
Date: Fri, 02 Feb 1996 15:49
Date: Fri, 02 Feb 1996 15:49
75 lines
3158 bytes
3158 bytes
marek@iiasa.ac.at (Marek MAKOWSKI) writes:
>I would like to ask for comments on three easy questions illustrated
>by the following piece of code:
>
>template <class I, class T>
>void mVect<I,T>::resize(I new_size) {
> T *old = v;
> v = new T[new_size]; // T *v is a private member of mVect
> int size_of_elem = sizeof(T); // <--- question 3
> //
> // do something
> //
> delete[] old; // <--- questions 1 & 2
>}
>
>I have the following questions:
>1. Is it absolutely robust and portable to delete[] old, even
> if a previous call was for new_size == 0 (or if v was allocated
> by the ctor for the size == 0) ?
The code
T *old = new T[0];
delete [] old;
is definitely perfectly legal (strictly conforming).
Whether or not it is in practice portable is another question -- that
is something that can only be determined empirically.
> In other words: is it guaranteed that:
> (v = new T[0]) == 0;
No, after 'v = new T[0]', it is guaranteed that `v' is *not* a null pointer.
>2. Is it correct to assume that no destructor is called by this statement
> if old was set as: old = new T[0] ??
Yes.
>3. Is there any risk involved in using sizeof(T) in this statement ?
Basically no, but of course that would depend on what you used it for.
>The Watcom code blows-up on the delete[] statement (if a previous
>call was for new_size == 0)
If what you have described is correct, then it sounds like a Watcom bug to me.
(However, I suspect there is a good chance that there is a bug somewhere
in the parts of your code that you haven't shown us.)
>and gives a warning whenever it sees the sizeof(T).
Compilers are allowed to warn about anything they like;
however I don't see why warning about `sizeof(T)' would be useful.
>If the answer for quaestions 1 and 2 is negative then I would like to
>know the reason why the standard does not require new to return 0
>for zero_size array of objects.
Well, an array of size zero is conceptually different to no array at all.
>If there is a good reason for allowing new to return "anything" in such
>situations then one should add to every ctor setting a ptr to 0
>(which indeed made the Watcom version of my application running).
--
Fergus Henderson WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au PGP: finger fjh@128.250.37.3
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is
summarized in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
]
Re: new T[0] and sizeof(T)
Author: Fergus Henderson
Date: Sat, 03 Feb 1996 14:46
Date: Sat, 03 Feb 1996 14:46
16 lines
1366 bytes
1366 bytes
clamage@Eng.Sun.COM (Steve Clamage) writes: >The expression "new T[0]" is invalid, but if you >use a non-const expression for the count, it is OK if the value is zero. What makes you think that the expression `new T[0]' is invalid? As I read the working paper, it seems perfectly legal, and the three compilers I tried it on were all quite happy to accept it. -- Fergus Henderson WWW: http://www.cs.mu.oz.au/~fjh fjh@cs.mu.oz.au PGP: finger fjh@128.250.37.3 --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: new T[0] and sizeof(T)
Author: Steve Clamage
Date: Mon, 05 Feb 1996 17:24
Date: Mon, 05 Feb 1996 17:24
50 lines
3138 bytes
3138 bytes
fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes: >clamage@Eng.Sun.COM (Steve Clamage) writes: >>The expression "new T[0]" is invalid, but if you >>use a non-const expression for the count, it is OK if the value is zero. >What makes you think that the expression `new T[0]' is invalid? >As I read the working paper, it seems perfectly legal, and the >three compilers I tried it on were all quite happy to accept it. I now believe I was wrong, and "new T[0]" is valid. Here's the background, if anyone is interested. A while back this question arose in another context and I studied the then-current draft very carefully. I came to the conclusion that "new T[0]" violated some explicit requirements. (I don't remember which version of the draft that was, but that is moot anyway.) When the question came up this time, I checked the "New" section of the current draft (5.3.4) and found a sentence that says that the value of any constant-expression must be strictly positive. In addition, the "Declarators" chapter of the draft has always said that an array type may be declared only if the number of elements is greater than zero. So I assumed that my earlier analysis was correct. Fergus posted an opinion that "new T[0]" was allowed, and I also received some private email on the subject, so I thought I should check more carefully. I re-read that paragraph and discovered the "strictly-positive" requirement doesn't apply to the first dimension of the array, but only to the second and subsequent dimensions. The first dimension must be non-negative. Then I checked with two people who deal with these sorts of issues in the C++ Committee. One at first made the same argument I did, but agreed when I showed how it didn't apply. Both believed this subject had never been explicitly discussed. We agreed that it was inconsistent to allow "new T[n]" when n==0 (which has always been allowed) but not "new T[0]". There also don't seem to be any technical difficulties in allowing the expression. (The new-expression yields type T*, not T[0].) -- Steve Clamage, stephen.clamage@eng.sun.com --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads