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
"William Gould, StataCorp LP" <[email protected]>
To
[email protected]
Subject
Re: st: Copying structures
Date
Mon, 15 Apr 2013 10:53:01 -0500
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/