This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fortran's C_CHAR type


Le 10/06/2015 16:38, Jan Hubicka a écrit :
>>> [jh@gcc2-power8 gcc]$ cat ../b.f90
>>> ! This testcase will abort if C_CHAR types are not interoperable
>>> module lto_type_merge_test
>>>   use, intrinsic :: iso_c_binding
>>>   implicit none
>>>
>>> contains
>>>   function types_test1(V) bind(c)
>>>     USE, INTRINSIC :: ISO_C_BINDING
>>>     CHARACTER(C_CHAR) :: types_test1
>>>     CHARACTER(C_CHAR), VALUE :: V
>>>     types_test1 = V
>>>   end function types_test1
>>> end module lto_type_merge_test
>>>
>>> [jh@gcc2-power8 gcc]$ cat ../a.c
>>> extern unsigned char types_test1 (char v);
>>> void
>>> main ()
>>> { 
>>>   if (types_test1 ('a') != 'a')
>>>     __builtin_abort ();
>>>   return 0;
>>> }
>>>
>>> As my fortran-fu goes, i think this testcase is correct. Fortran FE however
>>> builds types_test1 as a function return char but taking the array of size of 1
>>> as a parameter.
>> C_CHAR is a named constant of value 1 (the number of bytes of a char),
>> and character(foo) declares a string of length foo and default kind
>> (which is 1 for character types).
>> So it is expected that the argument is an array.
> 
> I see, what is the reason for assymetry for return value to not be array in this case?

There is this in gfc_sym_type:

  if (sym->ts.type == BT_CHARACTER
      && ((sym->attr.function && sym->attr.is_bind_c)
	  || (sym->attr.result
	      && sym->ns->proc_name
	      && sym->ns->proc_name->attr.is_bind_c)
	  || (sym->ts.deferred && (!sym->ts.u.cl
				   || !sym->ts.u.cl->backend_decl))))
    type = gfc_character1_type_node;
  else
    type = gfc_typenode_for_spec (&sym->ts);


And gfc_character1_type_node is defined as a plain char, it seems.
I don't know about the reason for either.

> 
>> If you want to declare a single character, you have to use an integer of
>> kind 1.
>> types_test1's result and v should have type integer(c_char), I think.
> 
> I will fix the testcase accordingly.  I basicallly copied what is in table
> 15.2 of the Fortran 2008 draft that explicitely lists Fortran type CHARACTER
> if kind C_CHAR compatible with "char". On the other hand there are no examples
> in the standard that would suggest that this should work this way.
> It only shows stuff like
>  CHARACTER(KIND=C_CHAR), DIMENSION(*) :: IN, OUT
> which corresponds to char []
> 
> Is my testcase supposed to work if I simply add KIND= before "C_CHAR"
> 
I have had a look at the table and the text around, and first I should
correct myself.
C_CHAR is 1, C_SIGNED_CHAR is 1, and the default values for len= and
kind= are 1 as well.
So, even if CHARACTER(KIND=C_CHAR) is what should be used as it's not
dependent on the implementation's default kind choice, it boils down to
the same as CHARACTER(C_CHAR), namely CHARACTER(len=1, kind=1) actually.


And about the line saying CHARACTER(KIND=C_CHAR) interoperable with char
in table 15.2:
You're right, while I would myself prefer to use an
INTEGER(KIND=C_SIGNED_CHAR) type, CHARACTER(KIND=C_CHAR) should be
supported as well.
That means that char should be compatible with char[1], I think.
You said there is no guarantee they are passed the same way?


> If you can look at the other c-bind testcases I produced, I would really appreachiate that.
I have looked at:
https://gcc.gnu.org/ml/gcc-patches/2015-06/msg00693.html
https://gcc.gnu.org/ml/gcc-patches/2015-06/msg00713.html
I saw nothing wrong with the tests.
Avoiding character interoperability avoids most of the pain. ;-)

Mikael


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]