- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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 kopiert
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
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.
- RSS-Feed abonnieren
- Thema als neu kennzeichnen
- Thema als gelesen kennzeichnen
- Diesen Thema für aktuellen Benutzer floaten
- Lesezeichen
- Abonnieren
- Drucker-Anzeigeseite