[comp.lang.c++] Semantics of argument passing

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''
-----------------------------------------------------------------------------