Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uunet!microsoft!jimad From: jimad@microsoft.UUCP (Jim ADCOCK) Newsgroups: comp.lang.c++ Subject: Re: reference parameters for overloaded operators Message-ID: <57015@microsoft.UUCP> Date: 28 Aug 90 19:29:30 GMT References: Reply-To: jimad@microsoft.UUCP (Jim ADCOCK) Distribution: comp.lang.c++ Organization: Microsoft Corp., Redmond WA Lines: 65 In article perez@csc.ti.com (Edward Perez) writes: > >jim, i understand what you mean by slicing and the problems one could get into. >however, when i compiled the code example using AT&T 2.0 06/30/89, i got the >following output: > >thing1_name <== thing1.Print() >thing2_firstname thing2_lastname <== thing2.Print() >thing1_name thing2_firstname thing2_lastname <== thing1.PW_v1(thing2); >thing1_name thing2_firstname thing2_lastname <== thing1.PW_v2(thing2); > >what do you get when you run your example through your compile ?? Interesting! -- When I use AT&T 2.0 06/30/89 followed by MSC 6.0 -Od [optimizations disabled] I get the following output: >thing1_name <== thing1.Print() >thing2_firstname thing2_lastname <== thing2.Print() >thing1_name thing2_firstname thing2_lastname <== thing1.PW_v1(thing2); >thing1_name thing2_firstname f <== thing1.PW_v2(thing2); -- which I believe represents correct behavior [in this case :-] of MSC 6.0 based on erroneous code generated from cfront. I say this based on manually studying the C code generated from cfront. I have a theory about why your compilation appears to "do the right thing", which I will discuss below. First of all, what I believe is a cfront error: When value copying thing2 into a temporary THING object, cfront first correctly copies the vtable ptr for a THING into the temporary THING's vtable ptr, then requests an eight-byte structural copy of the first 2/3rds of thing2s stucture on top of the temporary THING -- wiping out the pointer to the THING vtable, and replacing it with thing2s pointer to the THING2 vtable. Thus you end up with something that is suppose to be a temporary THING, but contains a THING2 vtable pointer. The temporary object then uses this erroneous THING2 vtable pointer to access a THING2 print method, which tries to access the second name, which doesn't exist in a THING structure. Thus, the garbage "f" is printed. I believe what cfront should be doing is first do the structural copy, and then set up the vtable pointer. Shouldn't a THING temporary object contain a pointer to the THING vtable? So how can the "apparently right" [actually wrong] thing be printed with your compiler? Well, my best guess is that your backend compiler is doing optimizations. The backend compiler recognizes via flow analysis that thing2 is no longer needed after the temp THING is created, and by gosh, it can actually avoid a lot of structural copying if it defines the temp THING as living at the same addresses previously occupied by thing2. So, by dumb luck, the temp THING gets a vtable pointer corresponding to a THING2 object, and by equally dumb luck, that object gets left with the corresponding extra field left over from the previous thing2 object at that address. Try turning off all C backend optimizations, and see if the code "stops working." Alternatively, maybe its just that I'm crazy. Can someone else in the know confirm or deny my interpretations, please? What I believe the correct final line of output should be is: thing1_name thing2_firstname -- In any case, pass by reference!