[Bug fortran/84885] c_char bind length

2018-03-16 Thread sgk at troutmask dot apl.washington.edu
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84885

--- Comment #6 from Steve Kargl  ---
On Fri, Mar 16, 2018 at 01:11:30PM +, mdblack98 at yahoo dot com wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84885
> 
> --- Comment #5 from mdblack98 at yahoo dot com ---
> I've been using Fortran since 1980 so caps is natural to me :-)
> My concern is that if gfortran has supported the len>1 convention for many
> years than perhaps it should continue supporting it to prevent breaking code
> like ours which will take some major effort to rewrite.Consider it an
> "extension" to gfortran which apparently it was.  Still fully 2018 compliant
> with this one little extension.  Enable it via a switch if you want to. 

First, gcc-bugzilla is probably not the appropriate forum
for learning nuances of BIND(C).  I suggest posting your
questions to the comp.lang.fortran newsgroup or Stack Overflow.

I've quoted two difference standards.  Both state

   If the type is character, the length type parameter is
   interoperable if and only if its value is one.

The above isn't a numbered constraint, so gfortran is not
obligated to tell a user that in the following

subroutine foo(c)
  use, intrinsic iso_c_binding
  character(len=1000, kind=c_char), bind(c) :: c
end subroutine foo

'c' is not interoperable.  Perhaps, gfortran should issue
at least a warning.  As long as a program does not try to
use 'c' in an interoperable manner, gfortran appears to
ignore the bind(c) attribute.  If a program, however, uses
'c' in an interoperable manner, the user may get a result
he expects even though it technically violates the Fortran
standard. 

Now, when you wrap the character statement in a derived type

subroutine foo(c)
  use, intrinsic :: iso_c_binding
  type, bind(c) :: bar
 character(len=1000, kind=c_char) :: c
  end type
  type(bar) bah
  bah%c = "123"
end subroutine foo

a numbered constraint comes into play.  gfortran must tell
the user that 'c' in type 'bar' is not interoperable.  I quoted
the relevant text already.  From F2018 (and similar appears in
other versions of the standard)

   C1806 (R726) Each component of a derived type with the BIND
   attribute shall be a nonpointer, nonallocatable data component
   with interoperable type and type parameters.

[Bug fortran/84885] c_char bind length

2018-03-16 Thread mdblack98 at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84885

--- Comment #5 from mdblack98 at yahoo dot com ---
I've been using Fortran since 1980 so caps is natural to me :-)
My concern is that if gfortran has supported the len>1 convention for many
years than perhaps it should continue supporting it to prevent breaking code
like ours which will take some major effort to rewrite.Consider it an
"extension" to gfortran which apparently it was.  Still fully 2018 compliant
with this one little extension.  Enable it via a switch if you want to. 

Making it a char array of 10 does not solve the problem as it doesn't behave
the same.  Maybe it should behave the same?
Here's my test Both gcc-7 and gcc-8 work fine without the "type" block.  So
comment out the type and end type lines and you get the correct output.But
including the type block causes both gcc-7 and gcc-8 to print out a floating
point number instead of the char string.  So the data type when inside the type
block is different than when it's outside the type block?  Or is there some
logical difference between len=1 c(10) and len=10 c?

#include 
#include 
void foo_(int *i,char *c,int);

int main()
{
    int i=123;
    char c[11];
    sprintf(c,"%s","1234567890");
    foo_(,c,strlen(c));
    return 0;
}

subroutine foo(i,c)
  use, intrinsic :: iso_c_binding, only: c_int,c_char,c_long

  type, bind(C):: params_block
    integer(c_int) :: i
    character(kind=c_char,len=1) :: c(10)
  end type params_block
    write(*,*) 'Testing'
    write(*,*) i
    write(*,*) c
end



Mike

On Thursday, March 15, 2018, 5:58:21 PM CDT, sgk at troutmask dot
apl.washington.edu  wrote:  

 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84885

--- Comment #4 from Steve Kargl  ---
On Thu, Mar 15, 2018 at 09:57:08PM +, mdblack98 at yahoo dot com wrote:
> 
> --- Comment #3 from mdblack98 at yahoo dot com ---
> I'll correct my reply in that using len > 1 outside of an interoperability
> block is OK.
> 
> So it is apparently now impossible to declare c_char len > 1 inside such a
> block?
> 

Steve Lionel is correct.  If you have a BIND(C) entity
and it involves the character type, then the length
parameter must be 1.  I quoted from a draft of the
upcoming F2018, because that is what I had at hand.  The
Fortran 2003 standard has essentially the same language:

F2003, page 398

  A Fortran derived type is interoperable with a C
  struct type if the derived-type definition of the Fortran
  type specifies BIND(C) (4.5.1), the Fortran derived type
  and the C struct type have the same number of components,
  and the components of the Fortran derived type have types
  and type parameters that are interoperable with the types
  of the corresponding components of the struct type.

Fortran 2003, page 396

  ...; if the type is character, interoperability also requires
  that the length type parameter be omitted or be specified
  by an initialization expression whose value is one.

You can specify an array of characters, e.g.,

type, bind(c) :: foo
  character(kind=c_char, len=1) :: c(10)
end type foo

PS: The name of the language is Fortran.  It hasn't been
written in all capital letters since 1990.

[Bug fortran/84885] c_char bind length

2018-03-15 Thread sgk at troutmask dot apl.washington.edu
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84885

--- Comment #4 from Steve Kargl  ---
On Thu, Mar 15, 2018 at 09:57:08PM +, mdblack98 at yahoo dot com wrote:
> 
> --- Comment #3 from mdblack98 at yahoo dot com ---
> I'll correct my reply in that using len > 1 outside of an interoperability
> block is OK.
> 
> So it is apparently now impossible to declare c_char len > 1 inside such a
> block?
> 

Steve Lionel is correct.  If you have a BIND(C) entity
and it involves the character type, then the length
parameter must be 1.  I quoted from a draft of the
upcoming F2018, because that is what I had at hand.  The
Fortran 2003 standard has essentially the same language:

F2003, page 398

   A Fortran derived type is interoperable with a C
   struct type if the derived-type definition of the Fortran
   type specifies BIND(C) (4.5.1), the Fortran derived type
   and the C struct type have the same number of components,
   and the components of the Fortran derived type have types
   and type parameters that are interoperable with the types
   of the corresponding components of the struct type.

Fortran 2003, page 396

   ...; if the type is character, interoperability also requires
   that the length type parameter be omitted or be specified
   by an initialization expression whose value is one.

You can specify an array of characters, e.g.,

type, bind(c) :: foo
   character(kind=c_char, len=1) :: c(10)
end type foo

PS: The name of the language is Fortran.  It hasn't been
written in all capital letters since 1990.

[Bug fortran/84885] c_char bind length

2018-03-15 Thread mdblack98 at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84885

--- Comment #3 from mdblack98 at yahoo dot com ---
I'll correct my reply in that using len > 1 outside of an interoperability
block is OK.

So it is apparently now impossible to declare c_char len > 1 inside such a
block?


Mike

[Bug fortran/84885] c_char bind length

2018-03-15 Thread mdblack98 at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84885

--- Comment #2 from mdblack98 at yahoo dot com ---
I got what's below from Steve Lionel of the FORTRAN working groupWith what
he said you flat should NOT be able to say anything other than LEN=1 for
c_char.  Whether it's in a type block or not.So the question becomes how to do
this...since this is likely to break a bit of FORTRAN code out in the
wild...like oursIt would appear you can't put a char array of any kind of
type block which we use for shared memory.

From Steve:
However, I don't see that Fortran 2018 has anything to do with this. The code
you show does not conform to Fortran 2003, which was the first revision to have
C interoperability. The issue is that in an interoperable type (a type declared
with BIND(C)), any entity of type CHARACTER must have length 1, because C
doesn't have the concept of character lengths. Instead you would make c here a
10-element array of single characters. It's ok outside of the type because
you're not declaring something interoperable then.

 Similarly, a dummy argument to an interoperable procedure can't have a
character length other than 1 up through Fortran 2008. In Fortran 2018, you're
allowed to use CHARACTER(*), but that requires that the corresponding C code
pass or accept a "C descriptor".

 That earlier versions of gcc allowed this to compile would be a bug in those
older versions.

--- 
Michael D. Black 

On Thursday, March 15, 2018, 11:42:40 AM CDT, kargl at gcc dot gnu.org
 wrote:  

 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84885

kargl at gcc dot gnu.org changed:

          What    |Removed                    |Added

            Status|UNCONFIRMED                |RESOLVED
                CC|                            |kargl at gcc dot gnu.org
        Resolution|---                        |INVALID

--- Comment #1 from kargl at gcc dot gnu.org ---
(In reply to mdblack98 from comment #0)
> subroutine foo(i,c)
>  use, intrinsic :: iso_c_binding, only: c_char
>        integer i
> 
>  type, bind(C) :: params_block
>        character(kind=c_char,len=10) :: c

I see length of 10 here.

>  end type params_block
>        write(*,*) 'X',c,'Z'
> end
> 
> This program fails to compile with gcc 8.0.1 20180304 -- but only if the
> character declaration is inside a type block
> Compiles fine with pre 8.0 compilers
> 
> gfortran -fPIC -g -c foo.f90
> foo.f90:6:42:
> 
>          character(kind=c_char,len=10) :: c
>                                          1
> Error: Component 'c' of BIND(C) type at (1) must have length one

From the F2018 standard,

18.3.2 Interoperability of intrinsic types

Table 18.2 shows the interoperability between Fortran intrinsic
types and C types.  A Fortran intrinsic type with particular type
parameter values is interoperable with a C type if the type and
kind type parameter value are listed in the table on the same row
as that C type.  If the type is character, the length type parameter
is interoperable if and only if its value is one.


C1806 (R726) Each component of a derived type with the BIND
attribute shall be a nonpointer, nonallocatable data component
with interoperable type and type parameters.

Your code is invalid, and the number constraint means
that gfortran must tell you about it.

[Bug fortran/84885] c_char bind length

2018-03-15 Thread kargl at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84885

kargl at gcc dot gnu.org changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 CC||kargl at gcc dot gnu.org
 Resolution|--- |INVALID

--- Comment #1 from kargl at gcc dot gnu.org ---
(In reply to mdblack98 from comment #0)
> subroutine foo(i,c)
>   use, intrinsic :: iso_c_binding, only: c_char
> integer i
> 
>   type, bind(C) :: params_block
> character(kind=c_char,len=10) :: c

I see length of 10 here.

>   end type params_block
> write(*,*) 'X',c,'Z'
> end
> 
> This program fails to compile with gcc 8.0.1 20180304 -- but only if the
> character declaration is inside a type block
> Compiles fine with pre 8.0 compilers
> 
> gfortran -fPIC -g -c foo.f90
> foo.f90:6:42:
> 
>  character(kind=c_char,len=10) :: c
>   1
> Error: Component 'c' of BIND(C) type at (1) must have length one

From the F2018 standard,

18.3.2 Interoperability of intrinsic types

Table 18.2 shows the interoperability between Fortran intrinsic
types and C types.  A Fortran intrinsic type with particular type
parameter values is interoperable with a C type if the type and
kind type parameter value are listed in the table on the same row
as that C type.  If the type is character, the length type parameter
is interoperable if and only if its value is one.


C1806 (R726) Each component of a derived type with the BIND
attribute shall be a nonpointer, nonallocatable data component
with interoperable type and type parameters.

Your code is invalid, and the number constraint means
that gfortran must tell you about it.