I convert -using the intrinsic transfer - a integer(c_int32_t) to a derived type composed of four bytes, does the standard says anything about the order of the bytes after conversion
program transfert_ex
use iso_c_binding
implicit none
integer(c_int32_t) :: res
type :: pixel
integer(c_int8_t) :: r
integer(c_int8_t) :: g
integer(c_int8_t) :: b
integer(c_int8_t) :: alpha
end type
type(pixel) :: p1, p2
integer(c_int32_t) :: rx = 33 !! 21
integer(c_int32_t) :: gx = 28 !! 1C
integer(c_int32_t) :: bx = 128 !! 80
integer(c_int32_t) :: ax = 255 !! FF
res = ieor(ishft(rx, 24), ieor(ishft(gx, 16), ieor(ishft(bx, 8), ax)))
p2 = transfer(res, p1)
!print "(4(z0,1x))", [p2%r, p2%g, p2%b, p2%alpha]
print *, ichar(transfer([p2%r, p2%g, p2%b, p2%alpha], 'a', 4))
end program transfert_ex
returns
211C80FF
255 128 28 33
It seems that the bytes are flip from left to right after the conversion. I test with three differents compilers (on the same architecture which is little endian) and it gives the same result. So maybe the order of the bytes in the derived type in taken into account by the standard ?
The bit manipulation procedures for integers like ieor()
or ishft()
use a Bit model defined in section 16.3 in the Fortran 2018 standard. It defines a sequence of bits from the most significant bit being the leftmost and the the least significant bit the rightmost. It does not care about how exactly the integer is stored in memory in some bytes.
If you do transfer()
you will see how such an integers are stored in memory in individual bytes. On a little-endian architecture that order will seem reversed. This is not controlled by the standard at all. It is defined by the implementation of memory storage for integers on the particular CPU in the particular setting (some CPUs can be set for either big-endian or little-endian).