Skip to content
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

Open
tbeu opened this issue Sep 10, 2015 · 23 comments
Labels

Comments

@tbeu
Copy link
Collaborator

tbeu commented Sep 10, 2015

As @sjoelund reported: External objects are not allowed in records

[HardwareIO.mo:9:5-31:21:writable] Error: Ignoring record component:
  ExternalObject Modelica_DeviceDrivers.HardwareIO.Comedi dh;
when building record the constructor. Records are allowed to contain only components of basic types, arrays of basic types or other records.
@bernhard-thiele
Copy link
Collaborator

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?

@tbeu
Copy link
Collaborator Author

tbeu commented Sep 11, 2015

I guess records came first and then external objects. But not sure at all. What do you suggest?

  • Remove comedi.
  • Fix comedi.
  • Make a MLS proposal to change records.

@sjoelund
Copy link
Contributor

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).

@tbeu
Copy link
Collaborator Author

tbeu commented Sep 11, 2015

What if is not considered as constructor but only has handle/void* pointer for the external object?

@sjoelund
Copy link
Contributor

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.

@tbeu
Copy link
Collaborator Author

tbeu commented Sep 11, 2015

There is no such thing as a reference (alias) to external object in Modelica.

Do you think this should be improved in MLS?

@sjoelund
Copy link
Contributor

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).

@tbeu
Copy link
Collaborator Author

tbeu commented Sep 11, 2015

Which is the other issue #54.

@bernhard-thiele
Copy link
Collaborator

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.

@sjoelund
Copy link
Contributor

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).

@tbeu
Copy link
Collaborator Author

tbeu commented Sep 11, 2015

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.

@sjoelund
Copy link
Contributor

You can pass it to records, sure. But the record is not allowed to return it.

@tbeu
Copy link
Collaborator Author

tbeu commented Sep 11, 2015

I see, finally. Constructing the ext. obj. in the record really is a bad idea.

@tbeu tbeu changed the title External objects are not allowed in records Construction of External objects is not allowed in records Sep 11, 2015
@tbeu tbeu changed the title Construction of External objects is not allowed in records Construction of external objects is not allowed in records Sep 11, 2015
@bernhard-thiele
Copy link
Collaborator

I don't see it. Any example where things would go wrong?

@tbeu
Copy link
Collaborator Author

tbeu commented Sep 11, 2015

How would you destrcut the ext. obj. that was constructed within the record? There is no such thing as a record dtor.

@sjoelund
Copy link
Contributor

That's actually not the problem either. The problematic use cases might not exist in this library at all.

@bernhard-thiele
Copy link
Collaborator

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.

@sjoelund
Copy link
Contributor

It is not that simple: you can create external objects that only live locally in a function call.

@bernhard-thiele
Copy link
Collaborator

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
recovering from errors in the function."

But what are the problematic cases that you think of?

@sjoelund
Copy link
Contributor

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.

@bernhard-thiele
Copy link
Collaborator

Do you mean alias in the sense of

MyExternalObject obj = MyExternObject();
MyExternalObject alias = obj;

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".

@sjoelund
Copy link
Contributor

Perhaps the alias was only used during initialization and then it was decided it could be removed?

@bernhard-thiele
Copy link
Collaborator

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.

@tbeu tbeu added the bug label Mar 19, 2016
@tbeu tbeu changed the title Construction of external objects is not allowed in records Modelica compatibility: Construction of external objects is not allowed in records Apr 30, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants