- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the previous version of the compiler, we have setup a nice system:
MODULE SMAVector use ISO_C_BINDING !----------------------------------------------------------------- TYPE, BIND(C) :: SMAVectorDouble integer(kind=4) :: len = 0 integer(kind=4) :: fin = 0 integer(kind=8) :: ptr = 0 ! pointer to the actual data CONTAINS procedure, pass :: At => SMAVectorDoubleAccess procedure, pass :: Append => SMAVectorDoubleAppend1 procedure, pass :: Load => SMAVectorDoubleLoad procedure, pass :: Free => SMAVectorDoubleFree procedure, pass :: Reserve => SMAVectorDoubleReserve END TYPE SMAVectorDouble !----------------------------------------------------------------- INTERFACE SMAVectorDoubleAppend subroutine SMAVectorDoubleAppend1(self,val) bind(C) import :: SMAVectorDouble type(SMAVectorDouble) :: self real (kind=8) :: val end subroutine END INTERFACE SMAVectorDoubleAppend INTERFACE INTERFACE function SMAVectorDoubleAccess(self, pos) bind(C) import :: SMAVectorDouble real (kind=8) :: SMAVectorDoubleAccess ! return the value of v(pos) type(SMAVectorDouble) :: self integer (kind=4) :: pos ! position in the array end function subroutine SMAVectorDoubleReserve(self, n) bind(C) import :: SMAVectorDouble type(SMAVectorDouble) :: self integer (kind=4) :: n ! number of doubles end subroutine subroutine SMAVectorDoubleFree(self) bind(C) import :: SMAVectorDouble type(SMAVectorDouble) :: self end subroutine END INTERFACE END MODULE
As you can see, this type is essentially a Fortran binding to std::vector. It contains the same data members: ptr ( raw pointer to allocated data ), len and fin. It contains bound methods, allowing for a simple use:
use SMAVector type(SMAVectorDouble):: v ! Declare v as Vector of doubles call v % Append(100.d0) call v % Append(200.d0) call v % Append(300.d0) do k = 1, v%len sum = sum + v % At(k) end do call v % Free()
The actual methods were implemented in C++. Everything worked, no problems.
This was with Intel(R) Fortran Intel(R) 64 Compiler XE Version 12.1.4.319.
Then came Intel(R) Fortran Intel(R) 64 Compiler, Version 16.0.1.150
Now everything fell apart.
It insists that derived types which have bound procedures cannot be declared with BIND(C) attribute.
If you remove BIND(C), C++ implementation cannot read the arguments anymore.
I found a workaround for this, which is nesting a 'BIND(C)' type inside the derived type, but it looks clumsy and non-elegant.
So, some questions for the experts:
1. Why was this done? Why was this neat interoperability abandoned?
2. Can it be restored?
Are there any !DEC directives that would change the behaviour to the old one ?
Are there really any performance benefits for not-storing the data members ( variables of a type ) in a way the C understands them?
Could we rally for the change of standard to allow derived types to be accessible from C/C++, even if they have methods bound to them?
You guys have obviously figured all of this out, in your compiler version 12, quite some time ago. Why did you have to break it for the newer versions?
Thanks,
-- Nick
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It was a compiler bug that allowed you to say that a type with type-bound procedures was interoperable. The standard explicitly says they are not.
C1504 (R425) A derived type with the BIND attribute shall not have a type-bound-procedure-part .
Fortran's interoperability is with C, not C++. While you may think that there is a correspondence between the Fortran type with type-bound procedures and a C++ structure with methods, the data passed for these is very different and not interoperable.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page