[gnu.g++.bug] array size expression for delete

rjc@CS.UCLA.EDU (Robert Collins) (02/27/90)

Michael,

When I use the syntax
	delete [size] array;
and compile with '-O -Wall',  I am told
	file.cc: warning: array size expression for delete ignored


This sounds ominous.  Is the [size] really ignored?  Is only the first
element of my array being destroyed?  Is the warning bogus?  Is my code
bogus?  Do you need some sample (bogus?) code?

My code seems to do the right thing (I should run out of CM memory fairly
quickly if this is failing to destroy all elements of the array, but I
don't), but this warning has got me worried.

Thanks,

Worried in LA
(rjc@cs.ucla.edu)

schmidt@crimee.ics.uci.edu (Doug Schmidt) (02/27/90)

In article <9002262348.AA12899@maui.cs.ucla.edu>, rjc@CS (Robert Collins) writes:
>Michael,
>
>When I use the syntax
>	delete [size] array;
>and compile with '-O -Wall',  I am told
>	file.cc: warning: array size expression for delete ignored
>
>
>This sounds ominous.  Is the [size] really ignored?  Is only the first
>element of my array being destroyed?  Is the warning bogus?  Is my code
>bogus?  Do you need some sample (bogus?) code?

Check the type of `array'.  If it is a pointer-to-built-in type, e.g.,
a char *, or int *, or double * then there is clearly no destructor,
so the `size' doesn't need to be used to free the memory (if the
compiler generates code to simply call free (array) this does the
trick).  On the other hand, if array points to objects of a
user-defined class type with a destructor then the size *does* matter
(since that many destructor calls must be made, one for each element
in the area pointed to by array).

Unless you've got an instance of the latter case I think everything is
ok!

  Doug
--
On a clear day, under blue skies, there is no need to seek.
And asking about Buddha                +------------------------+
Is like proclaiming innocence,         | schmidt@ics.uci.edu    |
With loot in your pocket.              | office: (714) 856-4043 |

rjc@cs.ucla.edu (Robert Collins) (02/27/90)

In article <25E9CB6A.19890@paris.ics.uci.edu> schmidt@crimee.ics.uci.edu (Doug Schmidt) writes:
>In article <9002262348.AA12899@maui.cs.ucla.edu>, rjc@CS (Robert Collins) writes:
>>When I use the syntax
>>	delete [size] array;
>>and compile with '-O -Wall',  I am told
>>	file.cc: warning: array size expression for delete ignored
>
>Check the type of `array'.  If it is a pointer-to-built-in type, e.g.,
>a char *, or int *, or double * then there is clearly no destructor,
>so the `size' doesn't need to be used to free the memory (if the
>compiler generates code to simply call free (array) this does the
>trick).  On the other hand, if array points to objects of a
>user-defined class type with a destructor then the size *does* matter
>(since that many destructor calls must be made, one for each element
>in the area pointed to by array).
>
>Unless you've got an instance of the latter case I think everything is
>ok!

Thanks Doug!  I went back and checked.  Although I was getting many
dozen's of these warnings, they were only in places where a simple
'free' would probably do alright.  For example, I had something like this:

	class NetNode { ... };
	NetNode **inputs;
	
	inputs = new NetNode*[num_inputs];
	for (i = 0; i < num_inputs; i++) {
		inputs[i] = new NetNode(/* hairy arg list */);
	}
	//...
	for (i = 0; i < num_inputs; i++) {
		delete inputs[i];
	}
	delete [num_inputs] inputs;	// warning on this delete

Unless I completely misunderstand what is going on, this warning kinda
seems like a Bad Thing.  If I am hacking the code, and change the type
of inputs to be NetNode*, there are destructors to call, and
the size expression in the delete is required.  Why am I getting warnings
about a valid construct?  If the compiler wants to ignore the fact that
I am treating it like an array of things, that is fine with me, as long
as it does the right thing.  If I remove the size expression, will I
get a warning?  No, because everything will work fine without it (and
g++ will probably be happier that way in any case).  If I change the
type of inputs to be NetNode*, and leave out the size expression, will
I get a warning?  I have not tried it, but Lippman implies that I will
not (and my destructors will not be called!).

This leads me to some questions for which I wouldn't mind getting some
answers:

In the case of my original code, should I remove the size expression?

In the case of my original code, will all reasonable compilers (gee, I
wish there were a standard definition of C++) do the right thing in
the absence of the size expression?  If not, I think g++ should not
produce this warning.

Is there a better way to do the sort of thing I am trying to do?  (I am
creating an array of user-defined objects, where the size of the
array is not known until run-time.  In addition, different elements
of the array require different constructors to be called.)  I would
happily avoid this whole issue.

How does the overloading of new and delete affect things?

Why is the size expression required at all?  G++ seems to correctly
handle `normal' dynamic arrays, even in the face of sizeof().  Why
can't the same thing be done with arrays of things created via new?
If the compiler knows how big the array is, and the type of the array,
it can determine how to call any destructors as appropriate.
I realize that it probably doesn't matter if it is doable, AT&T isn't going
to like it because it would be a pain to implement in `normal' C,
so it probably won't be in the C++ language definition.  It seems that
this is an easy thing to screw up (forget the size expression, or put
the wrong size).  I would appreciate a language that handled it
automagically.  If the language won't do it, then I would appreciate
a compiler that will warn me (even at run-time) about screwups.


I guess that is enough for now.  I am still not over the shock of compiling
my program with -Wall and getting many hundreds of lines of warnings
(fortunately, most were the result of the construct discussed above).
The rest of the warnings were about `unused' variables.  Actually, they
are instances of user defined types that remember a particular part of
the state of the world (like which Connection Machine processors are
currently turned on) in the constructor, and restore that state in the
destructor.  It is true that the variable is `unused' in the sense that
it is not referenced.  On the other hand, it is quite different from the
case of an unused integer.  The presence or absense of the integer
variable will not affect the semantics of the program.  The presence
or absence of a variable of a user-defined type can have unknown effects
on the semantics of the program.  Is it appropriate for the compiler to
flag instances of user-defined types as `unused' (unless the constructor
and destructor are completely visible and have no side effects)?

Now that is really enough.

Cheers,
rob collins
rjc@cs.ucla.edu

-------------------------------------------------------------------------------
rjc@cs.ucla.edu	                    C++/Paris on the CM2:  The only way to fly.
-------------------------------------------------------------------------------

rjc@CS.UCLA.EDU (Robert Collins) (03/02/90)

<From hansen@pegasus.att.com Thu Mar  1 09:48:40 1990
<
<[ discussion of delete size expressions: delete [size] foo; ]
<
<I said:
<< Why is the size expression required at all?  G++ seems to correctly handle
<< `normal' dynamic arrays, even in the face of sizeof().  Why can't the same
<< thing be done with arrays of things created via new?
<
<The next version of the C++ reference manual to come from Bjarne will do
<exactly that. The size expression has been deprecated (removed) from the
<language.

Is this for real?  When will this next version of the manual be released
to the world (or at least the compiler writers)?

If this is true, it is a Good Thing.

When can we expect to see such a thing implemented in g++?

Thanks for the info,
rob collins
rjc@cs.ucla.edu

<					Tony Hansen
<				att!pegasus!hansen, attmail!tony
<				    hansen@pegasus.att.com