Bookmark and Share

Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.


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

Re: st: Copying structures


From   Matthew White <[email protected]>
To   [email protected]
Subject   Re: st: Copying structures
Date   Mon, 15 Apr 2013 16:05:19 -0400

Thank you, Matt, and thank you, Bill, for the explanation. I've tried
-cp()-, and it works perfectly.

Best,
Matt

On Mon, Apr 15, 2013 at 11:53 AM, William Gould, StataCorp LP
<[email protected]> wrote:
> Matthew White <[email protected]> has found a bug in Mata and
> Matthew Baker <[email protected]> has verified it.
>
> We have verified it, too, and found the cause.  We will fix it, but
> that will not happen immediately and so let me explain how the problem
> arose and show you how to avoid it.
>
> Here is the simpliest example of the bug I can concoct:
>
>         mata:
>         struct mys {
>                 real scalar x
>         }
>
>         void myfunc()
>         {
>                 struct mys scalar me
>                 me.x = 1
>                 mysub(me)
>                 me.x
>         }
>
>         void mysub(struct mys scalar me)
>         {
>                 struct mys scalar test
>
>                 test = me[1]        // <- (1)
>                 // test = me        // <- (2)
>                 test.x = 3
>         }
>
>         myfunc()
>         end
>
> Choose line (1) and you will observe the bug. Choose line (2), and you
> will avoid the bug.  Because all the structures in this example are
> scalars, there is no reason to code line (1) but, by the same token, it
> is pefectly acceptable to subscript a scalar, and this example allowed
> us to trace the bug to lines like,
>
>             test = me[1]          /* me a structure or class */
>
> This problem has to do with opimization, but not with -set mataoptimize-
> on or off.  From the compiler's point of view, it is not necessary that
> test be a real variable and, to make code run faster, the compiler
> performed a trick.  In copying me[1] to test, it performed a "shallow
> copy".  A shallow copy is a new copy of me[1] itself, but all the members
> are linked back to the original.  The compiler incorrectly thought this
> shallow copy would be sufficieint.  In most circumstances, a shallow copy
> would have been sufficieint.  Think of the expression,
>
>             x = me[1].x + 2
>
> In this case, however, me[1] is the entire point of the expression and
> a "deep copy" of me needs to be made.  Mata is not doing that.
>
> We will fix this.
>
> In the meantime, either
>
>     1.  Never code
>
>             <something> = name[i]
>
>         where name is a struct or class if you are planning on changing
>         any of the members of <something>, or
>
>     2.  Code
>
>           <something> = cp(name[i])
>
>         where function cp() is defined as
>
>             transmorphic cp(transmorphic x)
>             {
>                   transmoprhic   y
>                     y = x
>                         return(y)
>             }
>
> Solution (2) forces the compiler to make the correct decision of making
> a deep copy of name[i].
>
> We checked and this bug since structures were first added to Mata and
> this is the first report we have had of it.
>
> -- Bill
> [email protected]
> *
> *   For searches and help try:
> *   http://www.stata.com/help.cgi?search
> *   http://www.stata.com/support/faqs/resources/statalist-faq/
> *   http://www.ats.ucla.edu/stat/stata/



-- 
Matthew White
Senior Project Associate
Innovations for Poverty Action
101 Whitney Avenue, New Haven, CT 06510 USA
www.poverty-action.org
*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/faqs/resources/statalist-faq/
*   http://www.ats.ucla.edu/stat/stata/


© Copyright 1996–2018 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   Site index