Closed sblionel closed 2 years ago
Some target architectures signal bus errors on misaligned memory references; others don't (at least not on some types of references) but can suffer silent performance degradation. So supporting misaligned components in general would be hard to make portable. You'd have to worry about whether to allow them as actual arguments and pointer targets, too.
Possible alternative solution for this use case, assuming that it was trying to use unformatted I/O on BMP files: make unformatted I/O of sequence &/or interoperable types skip over padding; i.e., the on-disk data would be packed, but the in-core data would be aligned. Easy to do, and wouldn't affect "normal" programs a all.
Are there use cases for misaligned components other than serialization and deserialization? It seems like this BMP case could also be handled in portable Fortran pretty easily with TRANSFER
to/from a byte array.
There are numerous APIs I have seen with misaligned fields, and the C headers for them have #pragma pack
. I agree, and in fact suggested to the user, that TRANSFER here would not be too annoying, but I can imagine other cases where it would be more complex. As I see it, this is an improvement to interoperability that is easy to explain and has minimal impact on the language.
Be advised, "#pragma pack" is not part of a C/C++ standard; neither is GCC's __attribute__((packed))
.
Will there be restrictions on references to misaligned components? Pointers to them? Usage as actual arguments? This is a feature that will have some subtle implications, if you want misaligned components to be first-class variables. For example, passing a misaligned component as an actual argument associated with an dummy with the TARGET
attribute requires additional semantics in the subclause that effectively limits the lifetime of validity of a pointer that's been aimed at the dummy argument, so as to allow for copy in/out.
(Unless you want to simply state that the program does anything but TRANSFER()
and unformatted I/O with misaligned components at its own risk, which would be what "minimal impact" on Fortran would have to look like.)
Thanks for that insight, @klausler . I am not conversant with the C standard and had thought that #pragma pack
was standard. Now that I know it isn’t, I would not support this.
I don’t see the issues you do with misaligned components - Fortran programs deal with these all the time in other contexts.
Thanks for that insight, @klausler . I am not conversant with the C standard and had thought that
#pragma pack
was standard. Now that I know it isn’t, I would not support this.I don’t see the issues you do with misaligned components - Fortran programs deal with these all the time in other contexts.
#pragma
is standard, but the specific pragmas are not. #pragma pack
is certainly a de facto standard. I think that you could define this feature in a usable way without needed to define it in terms of ISO C/C++ standards.
I was helping someone in the ifort forum where they wanted to declare a derived type for the BMP (bitmap) file header. This is a 14-byte structure with two misaligned 32-bit integers. The problem is that there is no standard Fortran way to declare this. A SEQUENCE type allows the compiler to insert padding but doesn't specify it - some compilers do by default, some don't. An interoperable type requires padding if the "companion C processor" would do so, and in the absence of
#pragma pack
, they generally would.I would like to see an option for declaring an interoperable type that says "do what the C processor would do if
#pragma pack
were in effect". A possible syntax would be:type, bind(C,PACK) :: mytype
Given my usual dislike of one-way options, I'd also want to see
NOPACK
as a choice.