I wanted a function to turn any scalar or vector type to bytes. The last
time I tried it I had to use TRANSFER directly, or specifically have
the type in a SELECT TYPE, which is method 1.
Now ifort 2023 gives me the same answer for all the cases, which is
what I expected. If I use -check all I get an error says CHARS has to
be allocated which is easy to work around but I consider incorrect;
other than that method 3 now does what I want.
gfortran 11 (do not have 12 currently on my platform) still gives me
answers I do not expect.
nvfortran compiles it, but I currently have problems with the loader so
I could not run it.
I have not had a chance to try it with anything else at this time.
I was preparing to search for/report the gfortran results as a bug,
but wondered if anyone sees something not standard-conforming or that
should produce different results?
When I tried this originally several of the features were new and everyone
failed in one way or another to even compile or execute. It is much
better now, but I am using a few features I do not use all that often,
so not totally sure all the methods are truly equivalent as far as the
results are concerned?
Reduce code sample
Module M_bytes
implicit none
private
public to_bytes1, to_bytes2, to_bytes3
interface to_bytes1; module procedure to_bytes1_arr, to_bytes1_scalar; end interface
interface to_bytes2; module procedure to_bytes2_arr, to_bytes2_scalar; end interface
interface to_bytes3; module procedure to_bytes3_arr, to_bytes3_scalar; end interface
contains
! no select type
function to_bytes3_arr(anything) result(chars)
class(*),intent(in) :: anything(:)
character(len=1),allocatable :: chars(:)
chars=transfer(anything,chars)
end function to_bytes3_arr
function to_bytes3_scalar(anything) result(chars)
class(*),intent(in) :: anything
character(len=1),allocatable :: chars(:)
chars=transfer(anything,chars)
end function to_bytes3_scalar
! default of select type
function to_bytes2_arr(anything) result(chars)
class(*),intent(in) :: anything(:)
character(len=1),allocatable :: chars(:)
select type(anything)
class default; chars=transfer(anything,chars)
end select
end function to_bytes2_arr
function to_bytes2_scalar(anything) result(chars)
class(*),intent(in) :: anything
character(len=1),allocatable :: chars(:)
select type(anything)
class default; chars=transfer(anything,chars)
end select
end function to_bytes2_scalar
! specific
function to_bytes1_arr(anything) result(chars)
class(*),intent(in) :: anything(:)
character(len=1),allocatable :: chars(:)
select type(anything)
type is (integer); chars=transfer(anything,chars)
type is (real); chars=transfer(anything,chars)
type is (character(len=*)); chars=transfer(anything,chars)
class default
stop 'unknown type'
end select
end function to_bytes1_arr
function to_bytes1_scalar(anything) result(chars)
class(*),intent(in) :: anything
character(len=1),allocatable :: chars(:)
select type(anything)
type is (integer); chars=transfer(anything,chars)
type is (real); chars=transfer(anything,chars)
type is (character(len=*)); chars=transfer(anything,chars)
class default
stop 'unknown type'
end select
end function to_bytes1_scalar
end module M_bytes
program testit
use M_bytes, only : to_bytes1, to_bytes2, to_bytes3
implicit none
integer :: i
character(len=1),allocatable :: chars(:)
write(*,"('select type and matching case')")
write(*,'(*(1x,z2.2))')to_bytes1([(i*i,i=1,10)])
write(*,'(*(1x,z2.2))')to_bytes1([11.11,22.22,33.33])
write(*,'(*(1x,z2.2))')to_bytes1('This is a string')
write(*,"('select type default')")
write(*,'(*(1x,z2.2))')to_bytes2([(i*i,i=1,10)])
write(*,'(*(1x,z2.2))')to_bytes2([11.11,22.22,33.33])
write(*,'(*(1x,z2.2))')to_bytes2('This is a string')
write(*,"('no select type')")
write(*,'(*(1x,z2.2))')to_bytes3([(i*i,i=1,10)])
write(*,'(*(1x,z2.2))')to_bytes3([11.11,22.22,33.33])
write(*,'(*(1x,z2.2))')to_bytes3('This is a string')
write(*,"('transfer variable array')")
write(*,'(*(1x,z2.2))')transfer([(i*i,i=1,10)],chars)
write(*,'(*(1x,z2.2))')transfer([11.11,22.22,33.33],chars)
write(*,'(*(1x,z2.2))')transfer('This is a string',chars)
write(*,"('transfer constant array')")
write(*,'(*(1x,z2.2))')transfer([(i*i,i=1,10)],[' '])
write(*,'(*(1x,z2.2))')transfer([11.11,22.22,33.33],[' '])
write(*,'(*(1x,z2.2))')transfer('This is a string',[' '])
end program testit
``
gfortran 11
select type and matching case
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00
8F C2 31 41 8F C2 B1 41 EC 51 05 42
54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
select type default
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00 8F C2 31 41 8F C2 B1 41 EC 51 05 42 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00
8F C2 31 41 8F C2 B1 41 EC 51 05 42 00 00 00 00 00 00 00 00 00 00 00 00
54
no select type
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00 8F C2 31 41 8F C2 B1 41 EC 51 05 42 01 00 04 09 10 19 24 31 40 51 64 8F C2 41 B1 EC 05 42 54 68 69 73 20 61 74 72 6E 67
8F C2 31 41 8F C2 B1 41 EC 51 05 42 01 00 04 09 10 19 24 31 40 51 64 8F
54
transfer variable array
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00
8F C2 31 41 8F C2 B1 41 EC 51 05 42
54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
transfer constant array
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00
8F C2 31 41 8F C2 B1 41 EC 51 05 42
54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
ifort 2023
select type and matching case
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00
8F C2 31 41 8F C2 B1 41 EC 51 05 42
54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
select type default
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00
8F C2 31 41 8F C2 B1 41 EC 51 05 42
54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
no select type
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00
8F C2 31 41 8F C2 B1 41 EC 51 05 42
54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
transfer variable array
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00
8F C2 31 41 8F C2 B1 41 EC 51 05 42
54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67
transfer constant array
01 00 00 00 04 00 00 00 09 00 00 00 10 00 00 00 19 00 00 00 24 00 00 00 31 00 00 00 40 00 00 00 51 00 00 00 64 00 00 00
8F C2 31 41 8F C2 B1 41 EC 51 05 42
54 68 69 73 20 69 73 20 61 20 73 74 72 69 6E 67