- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-standard-fortran-and-c-interoperability I copied code and changed only to cpp with extern"C". Iam getting error that I don't understand: error #6646: ALLOCATABLE or POINTER attribute dictates a deferred-shape-array. [RECVCOUNTS].
Fortran !******************************** module ftn_C_2 interface integer (C_INT) function CPP_Library_Function & (sendbuf, sendcount, recvcounts) & BIND(C, name='CPP_Library_Function') use, intrinsic :: ISO_C_BINDING implicit none type (C_PTR), value :: sendbuf integer (C_INT), value :: sendcount type (C_PTR), value :: recvcounts end function CPP_Library_Function end interface end module ftn_C_2 ! ftn_c.f90 ! ! FUNCTIONS: ! ftn_c - Entry point of console application. ! !**************************************************************************** ! ! PROGRAM: ftn_c ! ! PURPOSE: Entry point for the console application. ! !******************************************** program ftn_c use, intrinsic :: ISO_C_BINDING, only: C_INT, C_FLOAT, C_LOC use ftn_C_2 implicit none ! Variables INTEGER :: CRET real (C_FLOAT), target :: send(100) integer (C_INT) :: sendcount integer (C_INT), ALLOCATABLE, target :: recvcounts(100) ! ! Body of ftn_c ALLOCATE( recvcounts(100) ) ! CRET = CPP_Library_Function(C_LOC(send), sendcount, C_LOC(recvcounts)) ! print *, 'Hello World' end program ftn_c
CPP
extern "C" int CPP_Library_Function(void* sendbuf, int sendcount, int *recvcounts) { return 0x11; };
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Given the ALLOCATABLE attribute of 'recvcounts' array, the compiler is asking you to declare it using the deferred shape notation i.e., using colon syntax ":" rather than as fixed-size:
integer (C_INT), ALLOCATABLE, target :: recvcounts(:)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The example is wrong. The declaration of revcounts should be (:), not (100).
It's also a terrible example and its style should not be followed. I'll forgive, somewhat, the use of a C_PTR passed by value for the sendbuf argument, as until version 16 that was probably the best way to do that. I won't forgive use of C_PTR by value for recvcounts, this is just an INTEGER(C_INT) without VALUE.
Nowadays sendbuf should be declared in the interface as TYPE(*). In the caller, recvcounts doesn't need the TARGET attribute and should just be passed normally, not with C_LOC.
It's interesting that I have never seen this example before. I'll write up a request for an update/correction and send it to Intel.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks to both "best" answers. Is there documentation anywhere for current best interop practices?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know of documentation, but my view is "simpler is better". There's rarely need to fuss with C_PTRs, though sometimes it's required. Use the features the language provides, including TYPE(*) for void. Use VALUE only when the C prototype uses by-value. Be careful about character arguments, especially now that CHARACTER(*) is allowed in an interoperable interface, but it requires use of a "C descriptpor" on the C side.
I gave a presentation at the University of Tokyo recently on Fortran 2018, including the interop stuff. I'll post that in a separate topic. (Intel Fortran 16 and later supports all of the F18 interop features.)

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page