On a recent SO Q/A it came that the following code was not standard-conforming:
program foo USE iso_c_binding integer, allocatable :: a(:) character, allocatable, target :: c(:) integer, pointer :: p(:) integer :: n=1000, i a = [(i,i=1,n)] c = transfer(a,c) ! ... then later on ... call c_f_pointer( c_loc(c), p, [n] ) write(*,*) all(p == a) ! expected to print .true. end program
It is non standard because for
c_f_pointer the standard requires here
p to have the same type (hence being just an equivalent of
p => c), which is not the case.
C_F_POINTER(CPTR,FPRT,SHAPE): If the value of CPTR is the result of a reference to C_LOC with a noninteroperable effective argument X, FPTR shall be a nonpolymorphic pointer with10 the same type and type parameters as X
Yet it compiles without any warning/error with ifort and gfortran, and prints the expected result (
.true.)… which does not mean anything about the conformance.
But I wonder : how could it go wrong in practice? I cannot imagine a case where it wouldn’t work, actually.
There’s a variation of this code, using an interoperable intermediate type instead of
integer(c_signed_char), allocatable, target :: c(:)
Which is still non conformant in theory, but with a different case:
C_F_POINTER(CPTR,FPRT,SHAPE): If the value of CPTR is the C address of an interoperable data entity, FPTR shall be a data pointer with type and type parameter values interoperable with the type of the entity.