🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

5 total messages Started by Marek MAKOWSKI Thu, 01 Feb 1996 15:49
new T[0] and sizeof(T)
#3181
Author: Marek MAKOWSKI
Date: Thu, 01 Feb 1996 15:49
57 lines
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)
#3191
Author: Steve Clamage
Date: Fri, 02 Feb 1996 01:38
62 lines
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)
#3205
Author: Fergus Henderson
Date: Fri, 02 Feb 1996 15:49
75 lines
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)
#3224
Author: Fergus Henderson
Date: Sat, 03 Feb 1996 14:46
16 lines
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)
#3232
Author: Steve Clamage
Date: Mon, 05 Feb 1996 17:24
50 lines
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