Object with dynamic attribute in fortran - oop

I am programming in Fortran and I need to create an object class that has a dynamic vector as an attribute. Here is a minimal example of what I am trying to achieve.
MODULE my_class
PRIVATE
PUBLIC my_object
! define my object with a dynamic attribute
TYPE my_object
private
integer:: size;
real, allocatable:: tab(:); ! here the dynamic vector
CONTAINS
private
final:: destructor;
END TYPE my_object
! define an interface for object constructor
INTERFACE my_object
module procedure:: constructor;
END INTERFACE my_object
CONTAINS
! define constructor
FUNCTION constructor(size) RESULT(obj)
integer, intent(in):: size;
type(my_object):: obj;
obj%size= size;
allocate(obj%tab(size))
END FUNCTION constructor
! define destructor
SUBROUTINE destructor(this)
class(my_object):: this;
if (allocated(this%tab)) deallocate(this%tab)
END SUBROUTINE
END MODULE my_class
But I am not sure that is the proper way to do it. Is there not a risk of memory leaking with this implementation in case of multiple initializations? With this code for example :
PROGRAM test
USE my_class
IMPLICIT NONE
type(my_object):: obj;
obj= my_object(1000);
obj= my_object(3000);
END PROGRAM test
Has the obj%tab of the first instance been properly deallocated?
Or should I reimplement the equal operator?
Thanks for helping me to find out how Fortran deals with this.

Related

indirection operator of auto_gcroot class

auto_gcroot class does not have public indirection operator(operator*).
However, code sample below has been successfully compiled. Why is so?
auto obj = *(std::static_pointer_cast<const auto_gcroot<Object^>>(pObj))
std::static_pointer_cast returns a std::shared_ptr (In this case, a std::shared_ptr<const auto_gcroot<Object^>>), which does have an operator*.
*std::static_pointer_cast<T>(pObj) is an lvalue of type T, so obj will be a copy of the auto_gcroot<Object^> object stored by the shared_ptr.

SystemVerilog interface - Passing parameters after module declaration

Given the following module declaration:
module ( myinterface.mymodport mybus, ... );
And assuming that myinterface has parameters, how do I specify them?
The interface instantiation happens only in the testbench, but now I want to synthesize the DUT, so the TB disappears.
This is an oversight in the SystemVerilog LRM. There's no syntax to specify a required set of parameters for an interface in a module header.
You might check your synthesis tool to see if they provide any way of specifying parameter overrides for the top-level synthesis instance.
You specify the parameter when you instantiate the interface; you do not specify it in the port list of the module. Given
interface myinterface #(parameter DATA_SIZE = 0);
...
All you need is
module mymodule (myinterface.mymodport mybus);
...
because somewhere else you have
myinterface #(.DATA_SIZE(64)) i();
interface myinterface #(parameter DATA_SIZE = 0);
logic [DATA_SIZE-1:0] AWID;
logic [31:0] AWADDR;
modport mymodport (input AWID, AWADDR);
endinterface
module mymodule (myinterface.mymodport mybus);
initial
$display("mymodule");
endmodule
module top;
myinterface #(.DATA_SIZE(64)) i();
mymodule m (.mybus(i));
endmodule
https://www.edaplayground.com/x/528x

Return an inherited type from a method

Suppose I have the following classes defined:
Public Class BaseClass
...
End Class
Public Class DerivedClass
Inherits BaseClass
... Extra Fields, methods, etc ...
End Class
And then, in my code, I have a function with a signature of:
Public Function DoSomething(...) As List(Of BaseClass)
And when I try and return an object of type List(Of DerivedClass) from it, I get the error:
Value of type 'System.Collections.Generic.List(Of BaseClass)' cannot be converted to 'System.Collections.Generic.List(Of DerivedClass)'
I know not all the extra fields of the DerivedClass will be filled, but it would give me what I needed.
Is there a way to do this, or is this just considered bad programming practice? And, if so, what would be the right way to do this?
Have a look at this:
http://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx
Understanding Covariance and Contravariance will clear things up a bit :)
Covariance
Enables you to use a more specific type than originally specified.
You can assign an instance of IEnumerable (IEnumerable(Of Derived) in Visual Basic) to a variable of type IEnumerable.
Example:
IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;
Contravariance
Enables you to use a more generic (less derived) type than originally specified.
You can assign an instance of IEnumerable (IEnumerable(Of Base) in Visual Basic) to a variable of type IEnumerable.
Example:
Action<Base> b = (target) => { Console.WriteLine(target.GetType().Name); };
Action<Derived> d = b;
d(new Derived());
Invariance
Means that you can use only the type originally specified; so an invariant generic type parameter is neither covariant nor contravariant. You cannot assign an instance of IEnumerable (IEnumerable(Of Base) in Visual Basic) to a variable of type IEnumerable or vice versa.

VB.NET Using System.Threading.Volatile.Write on Enum var types

I am in need of performing a volatile write on a variable that is an Enum type derived from Byte, but I am stucked.
This is my (example) code:
Public Class MyOwnClass
Friend Enum MyEnum As Byte
Val1
Val2
End Enum
Private MyEnumVar As MyEnum = MyEnum.Val1
Friend Sub SetMyEnumVar(ByVal value As MyEnum)
System.Threading.Volatile.Write(MyEnumVar, value) 'Error!
End Sub
End Class
Since Threading.Volatile.Write is not provided with a signature with those arguments I get this error
Error 1 Overload resolution failed because no accessible Write can be called without a narrowing conversion:
With the list of all the overloads of the method.
CTyping the first argument is not working, because CType returns a casted value of course not with the same reference as MyEnumVar where the method gets the first parameter abviously ByRef instead.
CObject that would return a reference is also not viable because the method also hasn't got the overload for an object type other than Write(Of T)(T, T) where Tmust be a class type.
So how can I accomplish my purpose?
Thanks.
You can use the Write(Of T) overload where T is the type of Enum.
System.Threading.Volatile.Write(Of [Enum])(MyEnumVar, value)

system verilog /oop

The object in the below code has been instantiated just once, right? So the single object that has been instantiated should contain a single integer i field whose value is 2. Why does p.i give 1 instead of 2? Is this specific to SystemVerilog? Or do all oop languages behave similarly?
class Packet;
integer i = 1;
function integer get();
get = i;
endfunction
endclass
class LinkedPacket extends Packet;
integer i = 2;
function integer get();
get = -i;
endfunction
endclass
LinkedPacket lp = new;
Packet p = lp;
j = p.i; // j = 1, not 2
j = p.get(); // j = 1, not -1 or –2
Thanks
This example is pasted from section 8.13 of the the 1800-2009 SystemVerilog specification, which explains the issue. My opinion is that overriding class members like this is a really bad idea. The example in the specification is simply there to illustrate how it works.
The class property integer i is defined in both the base class and child class. This declaration in LinkedPacket overrides and hides the declaration in Packet.
From the specification:
In this case, references to p access the methods and class properties of the Packet class. So, for example, if
class properties and methods in LinkedPacket are overridden, these overridden members referred to
through p get the original members in the Packet class. From p, new and all overridden members in
LinkedPacket are now hidden.
Since you are calling the function through a handle to Packet you get the values from Packet.
In addition, the get() function is not declared virtual. This is why you do not see the integer being negated. This is also noted in the example in the specification.
To call the overridden method via a base class object (p in the example), the method needs to be declared
virtual (see 8.19).
This behavior is not unique to SystemVerilog and is similar to what you would observe in other OO languages.
If you want to have a different value for i in LinkedPacket, the proper way to do this would be to only declare i in the base class, and initialize it differently in the constructor.
e.g.
class Packet;
integer i;
function new();
i = 1;
endfunction
virtual function integer get();
get = i;
endfunction
endclass
class LinkedPacket extends Packet;
function new();
i = 2;
endfunction
virtual function integer get();
get = -i;
endfunction
endclass
I'm no SystemVerilog expert, but I'd expect p.i to return 1 as that is what you initialise it to. p.get() is just another way to return the same value, so that will also be 1.
j=get(); will (I think) return -2 - without an object prefix, I'd expect it to call the second function which is outside of the class.