Hi Orian --
I haven't had a lot of time to dig into your example today, but wanted to
make sure we got you a response before the end of the day. Others on the
team who are more expert with this part of the compiler/language may tag
onto what I say here. I also want to thank my colleague Vass for a lot of
help in creating this response.
I think your code is running afoul of a few things which the Chapel
compiler should be helping to guard you against but, unfortunately, isn't
at present.
First, as background, I want to make sure it's clear that if you're coming
from a C/C++ world, you should think of a Chapel record as being like a
struct/class and a Chapel class as being like a pointer to a struct/class.
The first issue that made me nervous in your code is that it hasn't been
our intention to support assignment overloads between Chapel class
variables. However, there is also currently nothing in the compiler that
prevents it. Personally, I get nervous that if assignment between classes
means anything other than "copy the rhs object pointer/ref into the lhs
one" that it could cause problems with core capabilities like
compiler-inserted temps/copies and type inference. By analogy, I believe
it's the case that while C++ permits assignment overloads between structs,
it doesn't support assignment overloads for pointers-to-structs (by
analogy, Chapel _does_ permit assignment overloads for records).
So one way you could proceed would be to create an 'assign()' function
that took the LHS not by-ref. This would be similar to the '=' overload
you created that generated the warning.
[As a sidebar, one of the ways we often work around this in our own code
is to create a record type that wraps a variable of the class type in
order to support assignment overloads, automatic memory management, and
the like on the record type without giving up the reference/identity
semantics that the class variable provides. We're working on some
features for the next release that will permit users to tap into such
record-wrapped-class patterns without having to write all the wrapper code
themselves].
The second issue may relate to how you declare your FockMatrix variable
(which is code that I don't think you included in your mail (?), so I'm
guessing at this point). Specifically, if FockMatrix was declared this
way:
var myMat = new FockMatrix();
then the Chapel compiler will infer the _static_ type of myMat to be
FockMatrix rather than SymmMatrix. And even though FockMatrix is a
subclass of SymmMatrix, this in itself is insufficient to support passing
a variable of static type FockMatrix to a formal of type ref-to-SymmMatrix
(as in C++). In order for that to be legal, you would also need to make
sure that 'myMat' has static type of SymmMatrix, as follows:
var myMat: SymmMatrix = new FockMatrix();
Here's a simple example that Vass put together that works:
class C { proc foo() { writeln("C::foo"); } }
class D: C { proc foo() { writeln("D::foo"); } }
proc bar (ref x: C) { x.foo(); x = new C(); x.foo(); }
proc main {
var myC: C = new D();
myC.foo();
bar(myC);
myC.foo();
}
whereas if the declaration of myC is changed to:
var myC = new D();
then the C compilation step fails with messages similar to the ones you
report. Vass also provides an example showing why this should be
problematic, if it's not obvious:
class C { }
class D: C { proc print { writeln(); } }
proc test(ref lhs: C) { lhs = new C(); }
var d = new D();
test(d);
d.print; // doesn't make sense when 'd' is actually a 'C'!
This is the second way that the Chapel compiler is failing you. It should
complain loudly about passing a variable of static type 'D' to a 'ref'
formal of type 'C' rather than letting it pass silently and having the C
compilation step blow up. Vass opened an issue and test to track this
problem today:
https://github.com/chapel-lang/chapel/issues/5353
https://github.com/chapel-lang/chapel/pull/5352
(and we should open one for assignment overloads on class types as well).
So, I'll be curious whether this is how you declared your SymmMatrix
variable, and if so, whether giving it a static type fixes the issue (but
then I'll still remain nervous about overloading assignment on it...).
Turning to some of the specific questions in your mail:
The origin of the problem seems to be that the compiler expect a SymmMatrix
not a FockMatrix (even if SymmMatrix is the superclass). But then I don’t
understand why I have a double pointer structure (struct
chpl_SymmMatrix_chpl_s **) vs a single pointer structure (struct
chpl_FockMatrix_chpl_s *).
It may be clearer by this point that one of these '*'s comes from the
'class' type ("pointer to struct" in C) and the other comes from the 'ref'
argument intent.
I am assuming that the overloaded operators of the superclass are valid for
the child classes.
Am I right?
Only if the child class variables have the superclass static type.
Hope this is helpful,
-Brad
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users