[Bug fortran/70739] New: VALUE attribute interpretation in a non-interoperable procedure
zmi007 at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed Apr 20 13:56:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70739
Bug ID: 70739
Summary: VALUE attribute interpretation in a non-interoperable
procedure
Product: gcc
Version: 6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: zmi007 at gmail dot com
Target Milestone: ---
I see difference between ifort and gfortran interpretation of a
non-interoperable procedure (without BIND(C)) with VALUE attribute in dummy
argument.
Actually gfortran gives (intuitively) expected result compared to ifort, but
this is something that is difficult to find out in standard to confirm.
See details here
https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/610807
(example)
/* test.c */
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
int32_t test (char* key, size_t len)
{
int32_t hash = 666;
printf("c key %s\n", key);
printf("c len %zu\n", len); // expected 2
return hash;
}
! test_main.f90
!-----------------------------------------------------------------------
!Module interface_module
!-----------------------------------------------------------------------
module interface_module
implicit none
interface
function test(key, length) result(hash) bind(c, name="test")
use iso_c_binding
character(kind=c_char),dimension(*) :: key
integer(c_size_t), value :: length
integer(c_int32_t) :: hash
end function test
end interface
abstract interface
function function_hash_template(key, length) ! <===== missing bind(c)
here !!!
use iso_c_binding
character(kind=c_char),dimension(*) :: key
integer(c_size_t), value :: length
integer(c_int32_t) :: function_hash_template
end function function_hash_template
end interface
contains
!-----------------------------------------------------------------------
!Function hash_wrap
!-----------------------------------------------------------------------
function hash_wrap(text, fun) result(hash)
use iso_c_binding
implicit none
character (len=*), target, intent(in) :: text
procedure(function_hash_template), pointer :: fun
integer(c_int32_t) :: hash
character(kind=c_char), dimension(len_trim(text)+1) :: text_c
integer(c_size_t) :: length
text_c = f_to_c_string(text) ! convert to c string for compatibility
length = len_trim(text) + 1
write(*,*) "hash_wrap, length = ", length
hash = fun(text_c,length)
end function hash_wrap
!-----------------------------------------------------------------------
!Function f_to_c_string
!-----------------------------------------------------------------------
pure function f_to_c_string (f_string) result (c_string)
use, intrinsic :: iso_c_binding, only: c_char, c_null_char
implicit none
character(len=*), intent(in) :: f_string
character(len=1,kind=c_char), dimension(len_trim(f_string)+1) :: c_string
integer :: n, i
n = len_trim(f_string)
do i = 1, n
c_string(i) = f_string(i:i)
end do
c_string(n + 1) = c_null_char
end function f_to_c_string
end module interface_module
!-----------------------------------------------------------------------
!Main program test_main
!-----------------------------------------------------------------------
program test_main
use interface_module
implicit none
write(*,*) test_wrap("1")
contains
!-----------------------------------------------------------------------
!Function test_wrap
!-----------------------------------------------------------------------
function test_wrap(text) result(hash)
use iso_fortran_env
implicit none
character(len=*),intent(in) :: text
integer(int32) :: hash
procedure(function_hash_template), pointer :: fun
fun => test
hash = int(hash_wrap(text, fun), int32)
end function test_wrap
end program test_main
Results:
gfortran:
gcc version 5.3.1 20160301 [gcc-5-branch revision 233849] (SUSE Linux)
gcc version 6.0.0 20160324 (experimental) [trunk revision 234449] (SUSE Linux)
hash_wrap, length = 2
c key 1
c len 2
666
ifort:
ifort version 16.0.2
hash_wrap, length = 2
c key 1
c len 140730916351912
666
Note the difference in len argument
Steve Lionel's comment to discuss here:
- [...]For a non-interoperable procedure, one without BIND(C), VALUE causes a
writable, temporary copy of the argument to be passed by reference. So in zmi's
case, the call through the procedure pointer, defined with an interface that
did not have BIND(C), caused the address of a copy of "length" to be passed.
More information about the Gcc-bugs
mailing list