Statalist


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: st: Stata classes


From   vwiggins@stata.com (Vince Wiggins, StataCorp)
To   statalist@hsphsun2.harvard.edu
Subject   Re: st: Stata classes
Date   Thu, 31 Dec 2009 14:05:25 -0600

Sergiy Radyakin <serjradyakin@gmail.com> asks,

> can somebody please explain why the results are different?
>
> version 11
>
> clear all
> .m=.object.new
> .m Declare string alpha="alpha"
> .m Declare string beta="beta"
> .m Declare string gamma="gamma"
> .m.gamma.ref=.m.beta.ref
> .m.beta.ref=.m.alpha.ref
> .m.alpha="new value"
> classutil des .m
>
> clear all
> .m=.object.new
> .m Declare string alpha="alpha"
> .m Declare string beta="beta"
> .m Declare string gamma="gamma"
> .m.beta.ref=.m.alpha.ref
> .m.gamma.ref=.m.beta.ref
> .m.alpha="new value"
> classutil des .m

Here are the results of running Sergiy's code (where I have annotated what the
assignment statements mean), 

---------------------------------- BEGIN  results --------------------

. version 11
. clear all
. .m=.object.new
. .m Declare string alpha="alpha"
. .m Declare string beta="beta"
. .m Declare string gamma="gamma"
. .m.gamma.ref=.m.beta.ref        // gamma now refers to what beta refers to
. .m.beta.ref=.m.alpha.ref        // beta now refers to what alpha refers to,
. .m.alpha="new value"            //      but that has no implication for
. classutil des .m                //      the prior statement; gamma still 
                                  //      refers to what beta referred to 
				  //      when that statement was executed

object .m:
   classwide:
        dbstyle      .dbstyle
   .Declare:
        string       .alpha         = "new value"
        string       .beta          = "new value"
        string       .gamma         = "beta"

. clear all
. .m=.object.new
. .m Declare string alpha="alpha"
. .m Declare string beta="beta"
. .m Declare string gamma="gamma"
. .m.beta.ref=.m.alpha.ref        // beta now refers to what alpha refers to
. .m.gamma.ref=.m.beta.ref        // gamma now refers to what beta refers to
. .m.alpha="new value"            //       which is what alpha refers to
. classutil des .m

object .m:
   classwide:
        dbstyle      .dbstyle
   .Declare:
        string       .alpha         = "new value"
        string       .beta          = "new value"
        string       .gamma         = "new value"

---------------------------------- END    results --------------------

As is often the case with pointers or references, this is all very subtle, but
the results are correct.

Basically, every variable in the class system holds a reference to its value.
When we assign one variable's reference to another variable's reference they
then refer to the same value.  Assignment order matters when assigning
references.  In the parlance of 3rd-generation languages, Sergiy's code never
created any pointers to pointers.  Instead it reassigned pointers.

Here is a very simple C program that replicates what happened in Sergiy's
Stata class program.  I am using integers instead of strings to avoid the
confusion that strings in C are already arrays and tend to use pointer
notation just to access their contents.  

If you are familiar with handling pointers in C, the program may help you
understand what is going on beneath Sergiy's class program.  If you are not,
just know that the program demonstrates what happens when my earlier statement
about every variable holding a reference is true.

---------------------------------- BEGIN --- ptrs.c --- CUT HERE -------
#include <stdio.h>

main (int argc, char **argv)
{
	int a=1, b=2, c=3 ;
	int *ap=&a, *bp=&b, *cp=&c ;

	printf("starting: *ap=%d, *bp=%d, *cp=%d\n", *ap, *bp, *cp) ;

	cp = bp ;
	bp = ap ;
	a = 4 ;
	printf("shuffle1: *ap=%d, *bp=%d, *cp=%d\n", *ap, *bp, *cp) ;

	ap=&a; bp=&b; cp=&c ; a = 1 ;			// reset
	printf("starting: *ap=%d, *bp=%d, *cp=%d\n", *ap, *bp, *cp) ;

	bp = ap ;
	cp = bp ;
	a = 4 ;
	printf("shuffle2: *ap=%d, *bp=%d, *cp=%d\n", *ap, *bp, *cp) ;
}
---------------------------------- END   --- ptrs.c --- CUT HERE -------

Here is the result of running ptrs.c, 

starting: *ap=1, *bp=2, *cp=3
shuffle1: *ap=4, *bp=4, *cp=2
starting: *ap=1, *bp=2, *cp=3
shuffle2: *ap=4, *bp=4, *cp=4

It is exactly the pattern that Sergiy saw from his Stata class program.

I fear that this reply may lead to a statalist ban on including C source code
in postings that do not involve plugins.


-- Vince 
   vwiggins@stata.com

*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index