ark@alice.UUCP (Andrew Koenig) (08/28/88)
In article <8808272341.aa21944@ROME.ICS.UCI.EDU>, schmidt@HARLIE.ICS.UCI.EDU ("Douglas C. Schmidt") writes: > Towards the bottom of page 180 in Stroustrup's book he states: > ``When an argument is passed a hitherto uninitialized variable, the > formal argument, is initialized.'' > Now, unfortunately, this does not seem to indicate what occurs if the > variable is already initialized. For example, consider the following code: ----------------------------------------- -> #include <stream.h> -> -> struct Test { -> private: -> int i; -> -> public: -> Test() {}; -> Test(int Foo) { -> i = Foo; -> } -> -> Test(Test& New) { -> cout << "yow\n"; -> i = New.i * New.i; -> } -> -> void Set_Value(int Value) { -> i = Value; -> } -> -> int Return_Value() { -> return (i); -> } -> }; -> -> static Test Foo(Test New) { -> return(New); -> } -> -> main() { -> Test Mytest; -> Mytest.Set_Value(8); -> Test Hitest = Mytest; -> cout << "Result 1 == " << Hitest.Return_Value() << "\n"; -> Mytest = Foo(Hitest); -> cout << "Result 2 == " << Mytest.Return_Value() << "\n"; -> } > ---------------------------------------- > Hitest, which is certainly initialized by the time it is passed as an > argument to Foo, has the constructor Test(Test& New) applied to its i > value twice, returning and assigning (64 * 64) * 4096 to Mytest's i. Running this under AT&T C++ gives a different result, which I think is correct, and which I'll explain. The program shown above defines a class Test with the property that initializing a Test object from another Test object squares the value along the way. In addition, member functions Set_Value and Return_Value can access this value directly. The main program first defines an object called Mytest and sets its value to 8. Then the declaration Test Hitest = Mytest; creates Hitest, initializing it from Mytest. This requires a call to Test(Test&), giving Hitest the value 64. All agreed so far. The question now is: what are the semantics of Mytest = Foo(Hitest); The correct answer, I believe, is that Test(Test&) should be applied twice more along the way, squaring 64 twice to give a value of 16777216 for Mytest. lskdfjlaskdjf Here's why. First of all, Mytest = Foo(Hitest); is equivalent to Test temp = Foo(Hitest); Mytest = temp; Test has no user-defined assignment operator, so assigning one Test to another is equivalent to assigning each of the elements of the Test structure -- in this case only the element `i' need be assigned. It may be possible for the compiler to generate code that avoids the use of the temporary, but the overall effect must be identical. What is the effect of Test temp = Foo(Hitest); The answer is that Test(Test&) must be called twice -- once to create the local variable New in function Foo and again to create the value of temp from New as part of the process of returning a value from Foo. Thus the value of temp should be 64 squared twice, or 16777216. Incidentally, note that if we change the definition of Foo just a little: static Test Foo(Test& New) { return(New); } then Test(Test&) is called only once when executing Test temp = Foo(Hitest); and the result is 4096. There's no way to avoid calling Test(Test&) at least once, though -- a constructor must be called for every instance of creating a new value. -- --Andrew Koenig ark@europa.att.com
paul@arthur.uchicago.edu (Paul Burchard) (08/29/88)
In article <8808272341.aa21944@ROME.ICS.UCI.EDU> schmidt@HARLIE.ICS.UCI.EDU ("Douglas C. Schmidt") writes: > >Towards the bottom of page 180 in Stroustrup's book he states: > >``When an argument is passed a hitherto uninitialized variable, the >formal argument, is initialized.'' > >Now, unfortunately, this does not seem to indicate what occurs if the >variable is already initialized. Perhaps changing the punctuation would make it clearer: ``When an argument is passed, a hitherto uninitialized variable (the formal argument) is initialized.'' The formal argument is the one whose initialization and ``hitherto uninitialized'' state are being discussed. ----------------------------------------------------------------------------- Paul Burchard paul@zaphod.uchicago.edu ``This quote intentionally'' -----------------------------------------------------------------------------