The 'contiguous' attribute does not enforce an array passed to a subroutine to be contiguous
pawosm-arm opened this issue · 0 comments
pawosm-arm commented
In a simple subroutine like that:
subroutine print_array(arr, m, n, h)
use iso_c_binding
implicit none
integer(kind=4), target, contiguous, intent(in) :: arr(:,:)
integer, intent(in) :: m, n, h
integer :: err
interface
function print_array_c(data, m, n) result(error_code) BIND(c)
import c_int, c_float, c_double, c_ptr
integer(c_int), VALUE, intent(in) :: m
integer(c_int), VALUE, intent(in) :: n
type(c_ptr), VALUE, intent(in) :: data
integer(c_int) :: error_code
end function print_array_c
end interface
err = print_array_c(c_loc(arr), m-h, n-h)
end subroutine print_array
The array passed as the first parameter is expected to be contiguous. When passing entire arrays, this works. But when a piece of array is passed, a new array of the sliced size is not being created, what is passed in the memory is still of the size of the original array, and from the sliced portion point of view, it is not contiguous, which is clearly visible in the called C code (it doesn't have to be C code, similar experiment using c_loc
and transfer
can be replicated in Fortran)
integer(kind=4), allocatable :: big_array(:, :)
...
allocate(big_array(n, m))
...
call print_array(big_array(1:n-h,1:m-h), m, n, h)
int print_array_c(const void *data, int m, int n)
{
const int *data_i = (const int *)data;
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
printf("%d ", data_i[i * n + j]);
printf("\n");
}
return 0;
}