hoff@bnlux0.bnl.gov (Lawrence T. Hoff) (02/08/91)
I haven't seen this question posted before, but I've only just started
reading this newsgroup, I apologize in advance if it is a FAQ.
When I am coding an algorithm which requires dynamic memory allocation,
but the total memory requirements are not known in advance, I use
realloc(), rather than malloc()/copy/free(), because realloc is generally
more efficient in that data is only copied if necessary, i.e. is sufficient
contiguous memory in unavailable. As posted many times here recently,
new should always be used with delete, and malloc/realloc should always
be used with free. One should not mix these allocation schemes.
My question is : Is there a 'renew' operator, i.e. a function which
acts like realloc, but works with memory allocated with the new operator?
If not, why not?
Some caveats come to mind, mostly they seem to follow the same theme :
This (renew) is potentially dangerous, one would have to exercise extreme
caution. However, this seems no more dangerous than realloc(), especially when
when dealing with intrinsic data types rather than arrays of class objects.
When dealing with arrays of class objects, there is of course the question
of how to do the copy (bitwise copy, assignment, or destroy/contruct),
otherwise I can't see any fundamental reason this would not be possible
to implement, with the caveat that whatever copy scheme was used might
not work with certain class objects.
Of course, I can accomplish what I want to do with a new/copy/delete
operation, chossing the most approprite copy scheme for the data type in
question, but why sacrifice efficiency when it's not necessary. I WILL
concede that one should perhaps not be concerned with efficiencies to any
great extent when one is dealing with dynamically allocated memory,
however this IS exactly why realloc() exists.
Comments? jbuck@galileo.berkeley.edu (Joe Buck) (02/08/91)
[ a proposal for a "renew" operator that works like realloc ]
You're free to propose a "renew" operator as an extension if
you want, but remember that new is not equivalent to malloc,
and delete is not equivalent to free; new calls a constructor
and delete calls a destructor. Often an object contains pointers
to other dynamic objects, so the delete call causes other
delete calls. What would renew do? Presumably you still need
a destructor and a constructor call. Would it do these and then
try to use the same block of allocated memory? If that's what
you want, you could implement it by overloading the new and
delete operators for the class where you want to get realloc()-
style behavior. The idea would be this: the delete operator
would keep the last block deleted, and new would try to use it
if possible. Here's an example of an implementation:
class MyClass {
public:
// other stuff
void* operator new (size_t);
void operator delete (void*, size_t);
private:
static void* lastBlock;
static size_t lastBlockSize;
}
void* MyClass :: operator new (size_t size) {
if (lastBlockSize == 0) return malloc(size);
else if (lastBlockSize >= size) {
lastBlockSize = 0;
return lastBlock;
}
else {
free(lastBlock);
lastBlockSize = 0;
return malloc(size);
}
}
void MyClass :: operator delete (void* p, size_t size) {
if (lastBlockSize > 0) free(lastBlock);
lastBlock = p;
lastBlockSize = size;
}
I think this kind of stuff can give you whatever advantages
you wanted from realloc(), and it's isolated from the rest of
the program. Overloading new and delete on a per-class basis
means that you can tune memory allocation however you want.
--
Joe Buck
jbuck@galileo.berkeley.edu {uunet,ucbvax}!galileo.berkeley.edu!jbuck chip@tct.uucp (Chip Salzenberg) (02/09/91)
According to jbuck@galileo.berkeley.edu (Joe Buck): >You're free to propose a "renew" operator as an extension if >you want, but remember that new is not equivalent to malloc, >and delete is not equivalent to free; new calls a constructor >and delete calls a destructor. How about a renew that is defined only for arrays? The "delete [] p" statement requires that the size of the allocated arrray be remembered by the implementation. So renew has the information it needs to call constructors and destructors appropriately. I would like to see something like: class X { ... }; X *p = new X[1]; // calls p[0].X::X() p = renew(p, 2); // calls p[1].X::X() p = renew(p, 1); // calls p[1].X::~X() delete [] p; // calls p[0].X::~X() Remember that the current definition of "::operator new()" loses all type information, so we need some language support for this feature to work. How about it? -- Chip Salzenberg at Teltronics/TCT <chip@tct.uucp>, <uunet!pdn!tct!chip> "Most of my code is written by myself. That is why so little gets done." -- Herman "HLLs will never fly" Rubin
horstman@mathcs.sjsu.edu (Cay Horstmann) (03/03/91)
In article <10895@pasteur.Berkeley.EDU> jbuck@galileo.berkeley.edu (Joe Buck) writes: >[ a proposal for a "renew" operator that works like realloc ] > >You're free to propose a "renew" operator as an extension if >you want, but remember that new is not equivalent to malloc, >and delete is not equivalent to free; new calls a constructor >and delete calls a destructor. Often an object contains pointers >to other dynamic objects, so the delete call causes other >delete calls. What would renew do? (stuff deleted) It is abundantly clear what renew should do. If the size of the renewed block is larger than the size of the current block, grow the current block (if possible) or copy the elements over with a bitwise copy to a new block, then RUN THE DEFAULT CONSTRUCTOR on the remaining (new) elements. If the renewed block is smaller, the top elements of the current block should be passed to the destructor. Note that this cannot be easily done with the array version of operator new. You must write some code like X* newptr = new X[newsize]; // runs the constructor newsize times for( int i = 0; i < oldsize; i++ ) newptr[i] = oldptr[i]; // runs X::operator= oldsize times delete[] oldptr; // runs the destructor oldsize times Clearly this is less than efficient. Contrast with a renew operator which just runs the default constructor newsize-oldsize times. I have a parametric variable array class that fakes the renew feature by allocating new char[size*sizeof(X)], then runs constructors and destructors with the placement syntax on each array element when necessary. But it doesn't work for non-class types (int's, pointers) or class types without both X::X(), X::~X() (e.g. Complex.) That is a real pain. SINCE I AM AT IT: It would be awful nice if operator new could zero out the memory when allocating arrays of integers or pointers (i.e. fill the array with the bit pattern corresponding to a logical zero.) Performance impact should be minimal, and since ints etc. don't have constructors, there is no good way for the programmer to achieve the same effect. This suggestion surely doesn't break any existing code. Cay
bright@nazgul.UUCP (Walter Bright) (03/12/91)
In article <1991Mar3.053504.14027@mathcs.sjsu.edu> horstman@mathcs.sjsu.edu (Cay Horstmann) writes:
/SINCE I AM AT IT: It would be awful nice if operator new could zero out
/the memory when allocating arrays of integers or pointers (i.e. fill the
/array with the bit pattern corresponding to a logical zero.)
Ah, but you can do it! Simply overload the global operator new to use
calloc. It's even portable!horstman@mathcs.sjsu.edu (Cay Horstmann) (03/14/91)
In article <281@nazgul.UUCP> bright@nazgul.UUCP (Walter Bright) writes: >In article <1991Mar3.053504.14027@mathcs.sjsu.edu> horstman@mathcs.sjsu.edu (Cay Horstmann) writes: >/SINCE I AM AT IT: It would be awful nice if operator new could zero out >/the memory when allocating arrays of integers or pointers (i.e. fill the >/array with the bit pattern corresponding to a logical zero.) > >Ah, but you can do it! Simply overload the global operator new to use >calloc. It's even portable! I cannot call such a solution portable. If my code relies on the global operator new doing one thing and your code relies on the global operator new doing something different, we cannot share code for the same program. (The ARM [p.60] has a similar comment.) I repeat my request that operator new should default to initializing the memory with the logical 0 value for the type allocated (almost always an all-0 bit pattern, but then who knows how 0 pointers or 0.0 floats are represented on some crazy systems.) ANSI, are you listening? Cay
daves@ex.heurikon.com (Dave Scidmore) (03/15/91)
In article <1991Mar14.042611.14921@mathcs.sjsu.edu> horstman@mathcs.sjsu.edu (Cay Horstmann) writes: >In article <281@nazgul.UUCP> bright@nazgul.UUCP (Walter Bright) writes: >>Ah, but you can do it! Simply overload the global operator new to use >>calloc. It's even portable! > >I cannot call such a solution portable. > >If my code relies on the global operator new doing one thing and your >code relies on the global operator new doing something different, we cannot >share code for the same program. (The ARM [p.60] has a similar comment.) > >I repeat my request that operator new should default to initializing the >memory with the logical 0 value for the type allocated (almost always an >all-0 bit pattern, but then who knows how 0 pointers or 0.0 floats are >represented on some crazy systems.) ANSI, are you listening? I think that *not* zeroing out memory should be the default. My reasons are as follows: 1) Zeroing is infrequently needed and seldom even helpful. 2) Any values needing initialization can be initialized by the constructor for the object. 3) Frequently the overhead for the constructor performing the initialization is little more than that required for initialization at allocation time. 4) If initialization needs to be done field by field then extra code is added to the constructor to perform that initialization. This would be code which is often not needed. 5) Initialization of objects at allocation time adds time to the allocation of *every* object when it is needed for only a few objects. 6) For large objects such as buffers in the megabyte range initialization time can result in visible delays while buffers are allocated. For such buffers initialization is usually not needed. 7) In addition to global operator new an objects operator new can be overloaded to initialize the memory if needed In summary it is my opinion (not that my opinion counts) that initialization of object upon allocation is of dubious benefit, and so is a waste of time and possibly code. I would prefer to see the spec remain the same. ANSI, are you listening? -- Dave Scidmore, Heurikon Corp. dave.scidmore@heurikon.com
horstman@mathcs.sjsu.edu (Cay Horstmann) (03/17/91)
In article <184@heurikon.heurikon.com> daves@ex.heurikon.com (Dave Scidmore) writes: >In article <1991Mar14.042611.14921@mathcs.sjsu.edu> horstman@mathcs.sjsu.edu (Cay Horstmann) writes: >> >>I repeat my request that operator new should default to initializing the >>memory with the logical 0 value for the type allocated (almost always an >>all-0 bit pattern, but then who knows how 0 pointers or 0.0 floats are >>represented on some crazy systems.) ANSI, are you listening? > >I think that *not* zeroing out memory should be the default. My reasons are >as follows: > > 1) Zeroing is infrequently needed and seldom even helpful. Huh? When you say X** a = new X*[100], isn't it most likely that you want all those X*'s to be null pointers? > > 2) Any values needing initialization can be initialized > by the constructor for the object. I was talking about new applied to NON-CLASS TYPES. They don't have a constructor. > > 3) Frequently the overhead for the constructor performing > the initialization is little more than that required for > initialization at allocation time. > Ditto. > 4) If initialization needs to be done field by field then extra > code is added to the constructor to perform that initialization. > This would be code which is often not needed. > > 5) Initialization of objects at allocation time adds time to > the allocation of *every* object when it is needed for > only a few objects. > > 6) For large objects such as buffers in the megabyte range > initialization time can result in visible delays while > buffers are allocated. For such buffers initialization > is usually not needed. Back here on planet Earth: operator new DOES CALL THE CONSTRUCTOR for every array element when allocating an array of objects. In C++ Ver. 2.0, it was not possible to call operator new on a class that didn't have a constructor with no arguments. I believe this has been relaxed in 2.1 -- a constructor with default arguments is called. > > 7) In addition to global operator new an objects operator new can > be overloaded to initialize the memory if needed > Yes and no. (Mostly no.) Both for non-class types and for ARRAYS OF CLASS TYPES, the global ::operator new is called. While it can be changed, that is not a good idea (ARM p.60) as a general purpose strategy. >In summary it is my opinion (not that my opinion counts) that initialization >of object upon allocation is of dubious benefit, and so is a waste of time >and possibly code. I would prefer to see the spec remain the same. ANSI, are >you listening? >-- I mostly care about arrays here. (I rarely do a char* p = new char;) Arrays of OBJECTS are initialized through a default constructor. You might get ANSI to rescind that, but I doubt it. My suggestion is to have the same safety when allocating arrays of non-class type. It is just fine with me if the initialization is restricted to arrays only, i.e. int* a=new int[100] zeroes them out, but int* a = new int; doesn't. It would allow the efficiency fanatics to get that single int allocated with stupendous speed. I really don't envy the ANSI people. I thought that my suggestion of initia- lizing arrays of non-class type obtained from ::operator new was the most harmless and innocuous suggestion. It breaks absolutely no old code. But I got more HATE MAIL about it than about the lvalue/rvalue operator[] stuff which, if adopted, would actually break code. Let me put this in perspective. If you want to allocate an array of 100 ints or pointers and for some reason don't want them initialized with zeroes, you can always use malloc. But if I want to write a template which allocates an array of X (maybe a class, maybe a basic type or a pointer), I cannot (at least with the ARM syntax) ask the template whether X is a class and either call new X[...] or calloc( sizeof(X)*... ). Cay
jbuck@galileo.berkeley.edu (Joe Buck) (03/19/91)
In article <1991Mar14.042611.14921@mathcs.sjsu.edu>, horstman@mathcs.sjsu.edu (Cay Horstmann) writes: |> I repeat my request that operator new should default to initializing the |> memory with the logical 0 value for the type allocated (almost always an |> all-0 bit pattern, but then who knows how 0 pointers or 0.0 floats are |> represented on some crazy systems.) ANSI, are you listening? How are you going to implement this? operator new is handed a size_t object and returns an object of type void. It doesn't know what type it's supposed to return. Or do you want to make the "default" operator new special (preventing a user from writing something similar)? Even if you could solve the technical problems, I'm still against it; it will just lead to lazy programming and subtle bugs (people will stop worrying about initializing every object member). Next you'll be asking for a guarantee that when I write void foo (int arg1) { char byteArray[BIGBUF]; int intArray[INTBUF]; ... } that byteArray and intArray be initialized to all zeros as well. If not, why not? Why should creating an array with new be different from making automatic variables? -- Joe Buck jbuck@galileo.berkeley.edu {uunet,ucbvax}!galileo.berkeley.edu!jbuck
tom@elan.Elan.COM (Thomas Smith) (03/20/91)
horstman@mathcs.sjsu.edu (Cay Horstmann): > In article <184@heurikon.heurikon.com> daves@ex.heurikon.com (Dave Scidmore) writes: >>In article <1991Mar14.042611.14921@mathcs.sjsu.edu> horstman@mathcs.sjsu.edu (Cay Horstmann) writes: >>> >>>I repeat my request that operator new should default to initializing the >>>memory with the logical 0 value for the type allocated (almost always an >>>all-0 bit pattern, but then who knows how 0 pointers or 0.0 floats are >>>represented on some crazy systems.) ANSI, are you listening? >> >>I think that *not* zeroing out memory should be the default. My reasons are >>as follows: >> >> 1) Zeroing is infrequently needed and seldom even helpful. > > Huh? When you say X** a = new X*[100], isn't it most likely that you want > all those X*'s to be null pointers? No. You're array might be null-terminated - in other words, you might do X** a = new X*[10000]; // notice the extra zeros a[0] = 0; // initialy empty - null first object The extra effort supplied by the compiler second-guessing what I the programmer intended to do is wasted effort. Furthermore, you may be allocating the array to be large enough to handle a possible extreme case in your program, rather than normal cases, thus it may need to be much larger than 100. Zeroing out 10s or 100s of thousands of bytes is not a trivial operation efficiency-wise. > I really don't envy the ANSI people. I thought that my suggestion of initia- > lizing arrays of non-class type obtained from ::operator new was the most > harmless and innocuous suggestion. It breaks absolutely no old code. For those of us actually developing products, "breaking code" is read as "taking a program with a certain behavior and changing it for the worse". Slowing down a program a perceptable amount by doing something beyond the control of the programmer certainly meets this description. > Let me put this in perspective. If you want to allocate an array of 100 > ints or pointers and for some reason don't want them initialized with > zeroes, you can always use malloc. But if I want to write a template which > allocates an array of X (maybe a class, maybe a basic type or a pointer), > I cannot (at least with the ARM syntax) ask the template whether X is a class > and either call new X[...] or calloc( sizeof(X)*... ). But you also said earlier > I was talking about new applied to NON-CLASS TYPES. They don't have > a constructor. In other words, there isn't any benefit in initializing objects that were due to be constructed (or possibly not), because that would be wasted effort. Your "template" example above contradicts this. Instead of adding wasted overhead for many legitimate algorithms, you should treat your specific case in its specific manner. If you want your memory initialized, then initialize it. If the language cannot descriminate between your useful initialization scenario and one that is detrimental in another case, then the language has to take the least common denominator. Thomas Smith Elan Computer Group, Inc. (415) 964-2200 tom@elan.com, ...!{ames, uunet, hplabs}!elan!tom
jadam@cs.tamu.edu (James P Adam) (03/20/91)
Newsgroups: comp.lang.c++ Subject: Friend Functions versus Friend Classes Summary: protected vs private Expires: References: <1991Mar16.172814.6525@mathcs.sjsu.edu> <966@elan.Elan.COM> Sender: Followup-To: Distribution: Organization: Computer Science Department, Texas A&M University Keywords: >I have a question about friend functions. > [stuff deleted] >class ToDoList { > friend Boolean Manager::Reprioritize(Bug& item, int priority); > private: > ThingList *things; >}; > >class InternalPerson { >private: > ToDoList ToDo; >}; > >class Manager : public InternalPerson { >public: > Boolean Reprioritize(Bug& item, int priority); // needs to look at ToDoList >}; It's hard to tell from this outline what exactly is going on inside the Reprioritize function (which is where the problem is, I assume). If you're trying to do something with the ToDoList "ToDo" that is declared in class InternalPerson, recognize that you can't access the information in a InternalPerson::ToDo directly from class Manager, since ToDo is declared "private" inside InternalPerson. If you want access to an InternalPerson::ToDo variable from class Manager, try making ToDo "protected" inside Internal person, instead of private. If this answer is off track, My Humble Appologies (MHA). If you wind up not getting the answer you want in the next day or so, you might consider posting a larger snippet of your code, esp. the code inside the function that is giving you the problems, plus the actual error/warning messages from the compiler. Jim
jbuck@galileo.berkeley.edu (Joe Buck) (03/21/91)
In article <1991Mar16.172814.6525@mathcs.sjsu.edu>, horstman@mathcs.sjsu.edu (Cay Horstmann) writes: |> In article <184@heurikon.heurikon.com> daves@ex.heurikon.com (Dave Scidmore) writes: |> > 1) Zeroing is infrequently needed and seldom even helpful. |> |> Huh? When you say X** a = new X*[100], isn't it most likely that you want |> all those X*'s to be null pointers? What about when you say void func() { X* arrayOfPointers[100]; ... } Wouldn't you want the pointers to be initialized in this case as well? What you're really proposing sounds like specifying a default constructor for non-class types (i.e. pointers get 0, doubles get 0.0, chars get '\0', etc). This has some advantages, but I would hope there'd be a way of turning it off for cases where it's wasteful. -- Joe Buck jbuck@galileo.berkeley.edu {uunet,ucbvax}!galileo.berkeley.edu!jbuck
horstman@mathcs.sjsu.edu (Cay Horstmann) (03/22/91)
In article <966@elan.Elan.COM> tom@elan.Elan.COM (Thomas Smith) writes: >>> >>> 1) Zeroing is infrequently needed and seldom even helpful. >> >> Huh? When you say X** a = new X*[100], isn't it most likely that you want >> all those X*'s to be null pointers? > >No. You're array might be null-terminated - in other words, you might do > X** a = new X*[10000]; // notice the extra zeros > a[0] = 0; // initialy empty - null first object >The extra effort supplied by the compiler second-guessing what I the >programmer intended to do is wasted effort. Furthermore, you may be >allocating the array to be large enough to handle a possible extreme case >in your program, rather than normal cases, thus it may need to be much >larger than 100. Zeroing out 10s or 100s of thousands of bytes is not >a trivial operation efficiency-wise. > This is an extremely rare case. In C++, it is not at all common to allocate such a large array right away just to handle a possible extreme case. It is much smarter to start out with a smaller array and grow it as needed with a variable array class. If you must allocate such a large array, and the penalty for zeroing it out is unacceptable, you can call malloc. To inject a little more realism into the discussion: Most processors have instructions that can zero out a memory block extremely quickly. But if you have lots of large blocks of memory "just in case", your program is much more likely to have to page them out, which is a zillion times more expensive. I continue to propose that operator new zero out arrays of non-class type, and that programmers who find that unacceptable use malloc. Cay
horstman@mathcs.sjsu.edu (Cay Horstmann) (03/22/91)
In article <12194@pasteur.Berkeley.EDU> jbuck@galileo.berkeley.edu (Joe Buck) writes: >In article <1991Mar16.172814.6525@mathcs.sjsu.edu>, horstman@mathcs.sjsu.edu (Cay Horstmann) writes: >|> In article <184@heurikon.heurikon.com> daves@ex.heurikon.com (Dave Scidmore) writes: >|> > 1) Zeroing is infrequently needed and seldom even helpful. >|> >|> Huh? When you say X** a = new X*[100], isn't it most likely that you want >|> all those X*'s to be null pointers? > >What about when you say > >void func() { > X* arrayOfPointers[100]; > ... >} > >Wouldn't you want the pointers to be initialized in this case as >well? What you're really proposing sounds like specifying a >default constructor for non-class types (i.e. pointers get 0, >doubles get 0.0, chars get '\0', etc). This has some advantages, >but I would hope there'd be a way of turning it off for cases where >it's wasteful. > > Joe, I wouldn't argue against that but I am not about to propose it myself. I like to live in peace. There is a reason why I am asking that operator new initialize arrays. If you write a template class for variable size arrays (of ints, char*, X,...) it would be desirable to rely on initialization in all cases since there is (at least with the current template syntax) no way of differentiating between class- and non-class types ("#if isclass(X)...") But in the case of a fixed array inside a single class, I guess one can have that class's constructor do the initialization. Cay
daves@ex.heurikon.com (Dave Scidmore) (03/22/91)
(Cay Horstmann) writes: >It is much smarter to start out with a smaller array and grow it as needed >with a variable array class. Not if the array could get very large as the copying of the old small array to the new large array can get extreemely expensive. >If you must allocate such a large array, and the penalty for zeroing it >out is unacceptable, you can call malloc. And if the zeroing of the array is mandatory, you can simply clear it after allocating it (which my original contention is won't be required often.) >To inject a little more realism into the discussion: Most processors have >instructions that can zero out a memory block extremely quickly. But if >you have lots of large blocks of memory "just in case", your program is >much more likely to have to page them out, which is a zillion times more >expensive. Assuming it is not a imbeded processor or a dedicated application which does not have a paging operating system to run under. >I continue to propose that operator new zero out arrays of non-class type, >and that programmers who find that unacceptable use malloc. One thing that occurred to me recently is that the proposal to zero memory on array allocation of built in types is inconsistent with the way class objects behave. Class objects can only call a constructor if one exists for the class being arrayed. This is to ensure that an array of class objects is initialized that same way an individual object of the same class would be. Built in types are not cleared upon allocation and in that sense they are similar to class objects with no constructor. Therefore an array of built in types should not be cleared since this is exactly the opposite of what happens when you only allocate a single built in type. The rules regarding calling the constructor for arrays of class objects were designed to provide arrays with class objects that are virtually identical to the non array ones. Proposing that built in type be cleared when appearing in an array but not individually does just the opposite. Requiring them to be cleared in all cases is inconsistent with class objects which are not cleared when no constructor exists. -- Dave Scidmore, Heurikon Corp. dave.scidmore@heurikon.com
gwu@nujoizey.tcs.com (George Wu) (03/23/91)
-
Concerning the ongoing debate of whether newly allocated objects should
have memory initialized to zero, I propose we make it a compiler command
line option. This will enable both camps to have the behavior they wish.
(I don't even want to get into an argument over what the compiler default
action should be. Actually, I do. The default should be to not initialize
memory on its own.)
Given this capability, I suspect developers would usually turn on the
zeroing option while an application is under development, and then turn it
off when the code is ready to be tested and shipped.
Does this fall within the ANSI committee's mandate? Or is this idea
too implementation oriented for their more language definition role?
George
----
George J Wu, Software Engineer | gwu@tcs.com or uunet!tcs!gwu
Teknekron Communications Systems, Inc.| (415) 649-3752
2121 Allston Way, Berkeley, CA, 94704 | Quit reading news. Get back to work.horstman@mathcs.sjsu.edu (Cay Horstmann) (03/24/91)
In article <12132@pasteur.Berkeley.EDU> jbuck@galileo.berkeley.edu (Joe Buck) writes: >In article <1991Mar14.042611.14921@mathcs.sjsu.edu>, horstman@mathcs.sjsu.edu (Cay Horstmann) writes: >|> I repeat my request that operator new should default to initializing the >|> memory with the logical 0 value for the type allocated (almost always an >|> all-0 bit pattern, but then who knows how 0 pointers or 0.0 floats are >|> represented on some crazy systems.) ANSI, are you listening? > >How are you going to implement this? operator new is handed a size_t >object and returns an object of type void. It doesn't know what type >it's supposed to return. Or do you want to make the "default" operator >new special (preventing a user from writing something similar)? I am not proposing to build this into operator new. Just like arrays of classes get initialized AFTER operator new is called, arrays of non-class objects would be initialized afterwards. You could still supply your own global operator new. > >Even if you could solve the technical problems, I'm still against it; >it will just lead to lazy programming and subtle bugs (people will >stop worrying about initializing every object member). Now I agree it would be AWFUL if people started worrying about initia- lizing every object member. For that reason, constructors should be BANNED from the language. Get real. Automatic initialization is one of the great features of C++. People have enough other things to worry about when writing programs. > >Next you'll be asking for a guarantee that when I write > >void foo (int arg1) { > char byteArray[BIGBUF]; > int intArray[INTBUF]; > ... >} > >that byteArray and intArray be initialized to all zeros as well. If not, >why not? Why should creating an array with new be different from making >automatic variables? I am not going to argue this. It is not a problem I often have when pro- gramming C++. It would be an incompatible change from C. I restrict my request to operator new which doesn't exist in C, and for which an alter- native exists (calling malloc) when the cost of zeroing out is considered excessive. Cay
steve@taumet.com (Stephen Clamage) (03/27/91)
gwu@nujoizey.tcs.com (George Wu) writes: > Concerning the ongoing debate of whether newly allocated objects should >have memory initialized to zero, I propose we make it a compiler command >line option... > Does this fall within the ANSI committee's mandate? Or is this idea >too implementation oriented for their more language definition role? The standardization effort cannot address issues such as command-line options. Not all compilers have command lines. "Compilation" might be distributed among various components of an integrated translation system. Taking the wider view, the C++ ANSI committee (X3J16) followed the lead of the C committee (X3J11) and rejected the idea of "optional features" or "levels of conformance". None of this prevents an implementation from providing additional features which do not conflict with requirements of the standard. Presumably nothing would prohibit the default 'operator new' from zeroing memory if an implementor felt this would be considered a benefit by potential customers. Personally, I think it would be more beneficial to set memory to 'impossible' values where this concept makes sense on a given architecture. Zeroing memory hides too many bugs involving uninitialized variables. (Unless zero is an 'impossible' value :-)). -- Steve Clamage, TauMetric Corp, steve@taumet.com