• Re: How can Fortran call a C library function without explicitly linkin

    From Steve Lionel@21:1/5 to Gary Scott on Wed Feb 23 15:58:14 2022
    On 2/23/2022 3:56 PM, Gary Scott wrote:
    You can, of course, use Fortran internal READ for this purpose as well.

    I wonder if there is an execution performance advantage or disadvantage
    in doing so?

    I would expect an internal READ to be slower, as it is potentially much
    more complex.

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to Beliavsky on Wed Feb 23 15:15:24 2022
    On 2/23/2022 2:24 PM, Beliavsky wrote:
    The command

    gfortran xatoi.f90

    where xatoi.f90 has the code below creates an executable. This is neat, but I am surprised that I don't need to use a C compiler. Where is the function atoi coming from?

    gfortran, like many Fortran compilers, uses libc as part of its runtime
    support for Fortran language semantics, and that means that the C
    runtime library gets automatically linked in with Fortran code. If you
    happen to make a call whose signature matches a libc routine, it will be
    found and used, and that's where atoi comes from.

    You can, of course, use Fortran internal READ for this purpose as well.

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to Steve Lionel on Wed Feb 23 14:56:26 2022
    On 2/23/2022 2:15 PM, Steve Lionel wrote:
    On 2/23/2022 2:24 PM, Beliavsky wrote:
    The command

    gfortran xatoi.f90

    where xatoi.f90 has the code below creates an executable. This is
    neat, but I am surprised that I don't need to use a C compiler. Where
    is the function atoi coming from?

    gfortran, like many Fortran compilers, uses libc as part of its runtime support for Fortran language semantics, and that means that the C
    runtime library gets automatically linked in with Fortran code. If you
    happen to make a call whose signature matches a libc routine, it will be found and used, and that's where atoi comes from.

    You can, of course, use Fortran internal READ for this purpose as well.

    I wonder if there is an execution performance advantage or disadvantage
    in doing so?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to Beliavsky on Wed Feb 23 15:11:18 2022
    On 2/23/2022 1:24 PM, Beliavsky wrote:
    The command

    gfortran xatoi.f90

    where xatoi.f90 has the code below creates an executable. This is neat, but I am surprised that I don't need to use a C compiler. Where is the function atoi coming from? For a C program (also listed below) there is a line

    #include <stdlib.h>

    to enable calls to atoi. In general, is an INTERFACE all you need to call a function in the C standard library https://www.csse.uwa.edu.au/programming/ansic-library.html ?

    ! from "Interoperation of Fortran with C"
    program main
    use, intrinsic :: iso_c_binding, only: c_char, c_null_char
    implicit none
    interface
    function atoi(in) bind(c)
    use, intrinsic :: iso_c_binding
    integer(c_int) :: atoi
    character(c_char) :: in(*)
    end function
    end interface
    integer :: i
    character(len=:,kind=c_char), allocatable :: digits
    allocate(character(len=5) :: digits)
    digits = c_char_'1234' // c_null_char
    i = atoi(digits) ! i gets set to 1234
    print*,"i=",i
    end program main

    Most, if not all, of the modern Fortran compilers are built by their corresponding C compilers using their C libraries. So most of those C libraries are available for usage by the Fortran code.

    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to Gary Scott on Wed Feb 23 15:16:49 2022
    On 2/23/2022 2:56 PM, Gary Scott wrote:
    On 2/23/2022 2:15 PM, Steve Lionel wrote:
    On 2/23/2022 2:24 PM, Beliavsky wrote:
    The command

    gfortran xatoi.f90

    where xatoi.f90 has the code below creates an executable. This is
    neat, but I am surprised that I don't need to use a C compiler. Where
    is the function atoi coming from?

    gfortran, like many Fortran compilers, uses libc as part of its
    runtime support for Fortran language semantics, and that means that
    the C runtime library gets automatically linked in with Fortran code.
    If you happen to make a call whose signature matches a libc routine,
    it will be found and used, and that's where atoi comes from.

    You can, of course, use Fortran internal READ for this purpose as well.

    I wonder if there is an execution performance advantage or disadvantage
    in doing so?

    atoi and atof are very efficient since they are hard coded to ASCII and
    have severe rules. Fortran internal reads and writes are directed by a
    format statement and fairly slow.

    I wrote an invoicing program for us back in 1976 or so on the Univac
    1108. I used formatted writes to write to an intermediate file. After
    a minute of cpu time, the job manager killed it. My boss had me change
    the formatted writes to unformatted writes. The program ran to
    completion in 10 seconds then.

    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Beliavsky@21:1/5 to All on Wed Feb 23 13:37:16 2022
    For

    digits = "1234"

    I wrote small programs to read an integer from digits 10^7 times using
    each of

    read (digits,*) i
    read (digits,"(i4)") i
    i = atoi(digits)

    and found that the last method calling C atoi() is much faster, both
    for Intel Fortran and gfortran on Windows. The times in seconds were

    gfortran ifort source
    12.770 3.549 xread_int.f90
    14.456 2.949 xread_int_fmt.f90
    0.416 0.362 xatoi_loop.f90

    The codes are at https://github.com/Beliavsky/Fortran-calling-C-for-IO .

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to Lynn McGuire on Wed Feb 23 15:19:29 2022
    On 2/23/2022 3:16 PM, Lynn McGuire wrote:
    On 2/23/2022 2:56 PM, Gary Scott wrote:
    On 2/23/2022 2:15 PM, Steve Lionel wrote:
    On 2/23/2022 2:24 PM, Beliavsky wrote:
    The command

    gfortran xatoi.f90

    where xatoi.f90 has the code below creates an executable. This is
    neat, but I am surprised that I don't need to use a C compiler.
    Where is the function atoi coming from?

    gfortran, like many Fortran compilers, uses libc as part of its
    runtime support for Fortran language semantics, and that means that
    the C runtime library gets automatically linked in with Fortran code.
    If you happen to make a call whose signature matches a libc routine,
    it will be found and used, and that's where atoi comes from.

    You can, of course, use Fortran internal READ for this purpose as well.

    I wonder if there is an execution performance advantage or
    disadvantage in doing so?

    atoi and atof are very efficient since they are hard coded to ASCII and
    have severe rules.  Fortran internal reads and writes are directed by a format statement and fairly slow.

    I wrote an invoicing program for us back in 1976 or so on the Univac
    1108.  I used formatted writes to write to an intermediate file.  After
    a minute of cpu time, the job manager killed it.  My boss had me change
    the formatted writes to unformatted writes.  The program ran to
    completion in 10 seconds then.

    Lynn

    I forgot to say that atoi and atof have almost no error checking in
    them. It is not unusual for a C program to crash in them because the
    caller passed a null pointer, etc. I have many guards around my calls
    to them in my asDouble and asInteger functions.

    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to Lynn McGuire on Wed Feb 23 18:36:40 2022
    On 2/23/2022 3:16 PM, Lynn McGuire wrote:
    On 2/23/2022 2:56 PM, Gary Scott wrote:
    On 2/23/2022 2:15 PM, Steve Lionel wrote:
    On 2/23/2022 2:24 PM, Beliavsky wrote:
    The command

    gfortran xatoi.f90

    where xatoi.f90 has the code below creates an executable. This is
    neat, but I am surprised that I don't need to use a C compiler.
    Where is the function atoi coming from?

    gfortran, like many Fortran compilers, uses libc as part of its
    runtime support for Fortran language semantics, and that means that
    the C runtime library gets automatically linked in with Fortran code.
    If you happen to make a call whose signature matches a libc routine,
    it will be found and used, and that's where atoi comes from.

    You can, of course, use Fortran internal READ for this purpose as well.

    I wonder if there is an execution performance advantage or
    disadvantage in doing so?

    atoi and atof are very efficient since they are hard coded to ASCII and
    have severe rules.  Fortran internal reads and writes are directed by a format statement and fairly slow.

    I wrote an invoicing program for us back in 1976 or so on the Univac
    1108.  I used formatted writes to write to an intermediate file.  After
    a minute of cpu time, the job manager killed it.  My boss had me change
    the formatted writes to unformatted writes.  The program ran to
    completion in 10 seconds then.

    Lynn
    I wrote my own ascii conversion routines for maximum performance where required. The question was academic.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Beliavsky on Wed Feb 23 17:41:31 2022
    On Wednesday, February 23, 2022 at 1:37:20 PM UTC-8, Beliavsky wrote:
    For

    digits = "1234"

    I wrote small programs to read an integer from digits 10^7 times using
    each of

    read (digits,*) i
    read (digits,"(i4)") i
    i = atoi(digits)

    You might also try

    sscanf(digits,"%d", i)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Lynn McGuire on Wed Feb 23 17:39:50 2022
    On Wednesday, February 23, 2022 at 1:19:33 PM UTC-8, Lynn McGuire wrote:

    (snip)

    I forgot to say that atoi and atof have almost no error checking in
    them. It is not unusual for a C program to crash in them because the
    caller passed a null pointer, etc. I have many guards around my calls
    to them in my asDouble and asInteger functions.

    Well, internal I/O won't do well if you pass it a null pointer, or otherwise invalid source string argument.

    But otherwise, there aren't many errors that atoi() can generate.
    The description is that it converts the initial portion of the string.
    It stops when it finds something that isn't allowed in a number.

    If there are no digits, that is a fine zero. There are no possible
    conversion errors, unlike Fortran.

    Note that if you want to compare to internal I/O, you might look
    at sscanf(), which is the C version of formatted internal input,
    and sprintf() for output. Or maybe snprintf() is a better choice.

    I suspect the speed of those is somewhere between atoi()
    and Fortran internal I/O.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ev. Drikos@21:1/5 to Beliavsky on Thu Feb 24 06:16:03 2022
    On 23/02/2022 21:24, Beliavsky wrote:
    ...

    to enable calls to atoi. In general, is an INTERFACE all you need to call a function in the C standard library https://www.csse.uwa.edu.au/programming/ansic-library.html ?

    ...

    Having a simple way, via a user defined interface, to call a standard C
    routine is of course better than nothing.

    IMHO however the approach can be error prone. In example, I've modified
    a little the interface in your code without face any linking errors and thereafter I changed the digits string from '1234' to '123456'. Finally
    the conversion caused some kind of overflow and the result is negative.

    Possibly such errors are just extreme cases or maybe compiler specific.

    Ev. Drikos

    -----------------------------------------------------------------------

    $ cat atoi.f90 && gfc atoi.f90 && ./a.out
    ! from "Interoperation of Fortran with C"
    program main
    use, intrinsic :: iso_c_binding, only: c_char, c_null_char
    implicit none
    interface
    function atoi(in) bind(c)
    use, intrinsic :: iso_c_binding
    integer(c_short) :: atoi
    character(c_char) :: in(*)
    end function
    end interface
    integer :: i
    character(len=:,kind=c_char), allocatable :: digits
    allocate(character(len=7) :: digits)
    digits = c_char_'123456' // c_null_char
    i = atoi(digits) ! i gets set to 1234
    print*,"i=",i
    end program main

    i= -7616

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From tth@21:1/5 to Ev. Drikos on Thu Feb 24 18:32:25 2022
    On 2/24/22 05:16, Ev. Drikos wrote:

       integer(c_short)  :: atoi

    mmmm, for me, atoi(3) don't return a short, bur an int.

    --
    +-------------------------------------------------------------------+
    | sphinx of black quartz, judge my vow. | +-------------------------------------------------------------------+

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)