Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!microsoft!jimad From: jimad@microsoft.UUCP (Jim ADCOCK) Newsgroups: comp.lang.c++ Subject: Re: operator++() and testing 'this' Message-ID: <58242@microsoft.UUCP> Date: 15 Oct 90 19:43:51 GMT References: <1990Oct14.224706.1934@nowhere.uucp> Reply-To: jimad@microsoft.UUCP (Jim ADCOCK) Organization: Microsoft Corp., Redmond WA Lines: 102 In article <1990Oct14.224706.1934@nowhere.uucp> sking@nowhere.uucp (Steven King) writes: > >In article <1990Oct9.144542.19983@sco.COM> jfischer@sco.COM (Jonathan A. Fischer) writes: >>In article <706@msor0.UUCP> kt@msor.UUCP (Keith Tizzard) writes: >>>Two questions about C++ >>> >>>2 Testing of and assigning to 'this' >>> >>>Is it still possible to assign to 'this' in V2.0? >> >> Technically, you can't assign to this, since it's "X * const this". >>BUT, it's listed in Appendix B.3.3 as an "anachronism," something that is >>provided for compatibility with earlier releases of cfront. I.e., you can do >>it, but technically you shouldn't. Also, there is no requirement for a >>compiler vendor to implement these anachronisms, so you are tainting your >>portability by using them. >> >>>Can one rely on 'this' having the value zero on entry to the constructor >>>if the object is allocated on the free store? >> >> Yep, according to the same anachronisms section. > > And only if the object isnt a member (or base) of another object. >Even tho' the translator knows this information (it does pass a flag to >destructors) there is NOT a reliable mechanism to determine this from within >a constructor. Good point. Embedded objects are another good example why C++ compilers DO NOT typically support the (this==0) test to see if objects are on the heap or not. I haven't seen a C++ compiler released in years that supports this test. Correct me if you find a counter-example. The reason that compilers DO NOT support this test is quite simple: Later changes in the language require that constructors not be invoked on failed allocations. So, if a failed allocator returns a null pointer [because its out of memory, for example], then the constructor must short circuit to a no-op. And how can a no-op check to see if (this==0) and take some specified action if it is??? So, reasonable speaking, compilers have the option of supporting today's definitions of how its suppose to work, or yesterday's definition. Most compilers choose today's definition, guaranteeing that a constructor will never be invoked when (this==0), making a (this==0) test inside a constructor kind of pointless. > I wonder if there is enough of a need for this to consider adding it >to the language... As mentioned above, it would do nothing to add support for the (this==0) test inside a constructor, because constructors must short-circuit to a no-op if (this==0), because constructors are never invoked on a failed allocation. However, there's other practical reasons why the heap verses stack test can't be done: Programmers have the option to dynamically allocate objects on the stack using the placement version of new: void doSomethingWithFooBar(int i) // not intended to be a "good" example { char space[100]; if (i) { FOO& foo = *new(space) FOO; foo.doIt(); } else { BAR& bar = *new(space) BAR; bar.doit(); } } Thus, various flavors of the overloaded "new" operator could actually be returning space on the stack. Conversely, it is not uncommon for C++ programmers to create "light-weight" processes, whose stack space is not uncommonly allocated out of heap. Thus stack space, might actually be heap space, or using the above example, heap space might actually be stack space might actually be heap space.... To my mind, the right thing to do is to keep the language out of these non-portable issues. Usually, programmers can arrange for some simple, if non-portable test to see if an object is "on the stack" char* pstackstart; int main() { char stackstart; pstackstart = &stackstart; theRealMain(); } int isOnStack(OBJECT* pobject) { char c; char* pstackend; pstackend = &c; // reverse the order of the following test depending on whether your stacks // grow up or down: return (pstackstart < (char*)pobject) && (pstackend > (char*)pobject); } If pstackstart were a process global, rather than a system global, and initialized at process startup time, this could also work with lightweight processes. Depending of course, on what you really intend by testing if a object is "on the stack" ????