Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Fortran Calling C Example Docs

MWind2
New Contributor III
412 Views

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;
};

 

0 Kudos
4 Replies
FortranFan
Honored Contributor II
412 Views

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(:)

 

0 Kudos
Steve_Lionel
Honored Contributor III
412 Views

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.

0 Kudos
MWind2
New Contributor III
412 Views

Thanks to both "best" answers. Is there documentation anywhere for current best interop practices?

0 Kudos
Steve_Lionel
Honored Contributor III
412 Views

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

0 Kudos
Reply