Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!ucla-cs!rjc@cs.ucla.edu From: rjc@cs.ucla.edu (Robert Collins) Newsgroups: gnu.g++.bug Subject: Re: array size expression for delete Message-ID: <32311@shemp.CS.UCLA.EDU> Date: 27 Feb 90 02:26:49 GMT References: <9002262348.AA12899@maui.cs.ucla.edu> <25E9CB6A.19890@paris.ics.uci.edu> Sender: news@CS.UCLA.EDU Reply-To: rjc@cs.ucla.edu (Robert Collins) Distribution: gnu Organization: UCLA Computer Science Department Lines: 106 Dexpires: 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. -------------------------------------------------------------------------------