-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modelica compatibility: Construction of external objects is not allowed in records #93
Comments
Hm, the restrictions imposed on external objects seem quite arbitrarily to me. Things should compose in a language. It seems odd to me that this would not be allowed and I think it can only be indirectly deduced from the MLS from the sentence that restricts the elements of records to "only contain components of specialized class record and type". Is there some more explicit reasoning why it should be not allowed? |
I guess records came first and then external objects. But not sure at all. What do you suggest?
|
The reason is that only external object constructors are allowed to return external objects, in order to disallow any function except constructors to create new external objects (so all constructed objects can be destructed later on). |
What if is not considered as constructor but only has handle/void* pointer for the external object? |
There is no such thing as a reference (alias) to external object in Modelica :( And external functions returning Integer are not large enough to hold a void* either. |
Do you think this should be improved in MLS? |
I think the only reason to allow aliases to external objects would be in order to make connection sets involving external objects (to propagate them). |
Which is the other issue #54. |
People actually misused Integer to hold void*. That worked fine as long as Dymola code was 32 bit. Now, we still could have a hack using "doubles" to hold a reference or misuse an Integer array. But having a concept like external objects and resorting to such workarounds makes me scream. I'm not sure whether they even thought on external objects when restricting the valid elements for records. I would propose to change the specification since I don't see any reason why allowing it would make problems. The external object is created by its own constructor, so constructing and destructing objects should be perfectly fine from my understanding. |
We didn't restrict the valid elements for records: we restricted where an external object can be assigned. They are assign once (at initialization or function entry). This was done for a good reason (some tools did not call the destructor, or called it twice if weird things were done with external objects). |
A constructed external object is a void* pointer that only can passed to external functions. Why should it be not possible to pass it to records or connectors? I agree with @bernhard-thiele here that this should be allowed. |
You can pass it to records, sure. But the record is not allowed to return it. |
I see, finally. Constructing the ext. obj. in the record really is a bad idea. |
I don't see it. Any example where things would go wrong? |
How would you destrcut the ext. obj. that was constructed within the record? There is no such thing as a record dtor. |
That's actually not the problem either. The problematic use cases might not exist in this library at all. |
I don't know how external objects are implemented in Dymola or OpenModelica. But a first idea would be to keep track at initialization whenever an external object is generated and add a callback to the destructor in a list like structure. If simulation finishes just iterate over the list and call the destructors. |
It is not that simple: you can create external objects that only live locally in a function call. |
Ok. That would need to be handled as a special case, similar to how the MLS proposes it: "External objects may be a protected component (or part of one) in a function. The constructor is in that case called at the start of the function call, and the destructor when the function returns, or when But what are the problematic cases that you think of? |
If you allow aliases, you cannot do that. Because there might be another live version of the same external object somewhere. And you could do things like alias an external object, destruct the object and return the alias to the new loose pointer. |
Do you mean alias in the sense of
That wouldn't change anything. At simulation end or at simulation failure I would still just go through my list of destructors and call them. I'm trying to think of a situation in a Modelica simulation in which one alias could live longer than another, but since there is no dynamic creation of objects during runtime (except for scope restricted function calls) I can't think of a problematic case. Note that "It is not legal to call explicitly the constructor and destructor functions". |
Perhaps the alias was only used during initialization and then it was decided it could be removed? |
Hm, this sounds like a tool optimization to look for variables that are only used at initialization time and discard them. If that optimization is performed, a tool might need to do additional checks for external objects. But this is an optimization issue and also seems orthogonal to allowing external objects as elements of records (as soon as you do that optimization you have to check for alias variables anyway). From a semantics point of view it is not possible to declare a variable that can be only accessed during initialization. If a variable is declared once, it is potentially accessible during the whole simulation. |
As @sjoelund reported: External objects are not allowed in records
The text was updated successfully, but these errors were encountered: