- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
From another source, I am receiving binary files in which the fields are not aligned. I am reading these files under C++, using a C++ struct which is "packed", like this:
#pragma pack(push,1)
struct Unaligned
{
char c;
int i;
};
In C++, "pack" means the fields of the struct occupy successive bytes, with no padding added for alignment.
In Fortran, I need to write a file in the same format. I cannot find anything analogous to the C++ `pragma pack`. I did find a post by Steve Lionel from 2017, in response to a similar question:
"...components do get padding for natural alignment by default in Intel Fortran. You can disable this by 1) Making the type a BIND(C) type, 2) Specifying /noalign when compiling, 3) bracket the type declaration with !DIR$ OPTIONS /NOALIGN ... !DIR$ END OPTIONS, 4) Make the type a SEQUENCE type (not recommended)"
In Fortran, I have, for example,
TYPE, BIND(C) :: Unaligned
INTEGER(C_CHAR) :: c
INTEGER(C_INT) :: i
END TYPE Unaligned
TYPE(Unaligned), TARGET :: hdr ! TARGET allows a pointer, for debugging
I am opening an output file with
OPEN(UNIT = ioXLI, FILE = TRIM(path), FORM = 'unformatted', ACCESS = 'stream', status = 'replace')
and writing my unaligned derived type with
WRITE(ioXLI, IOSTAT = status) hdr
Now I have two problems: (1) the Fortran derived padding added; and (2) the output file has what I presume is a 4-byte record length written before the values in `hdr`, which cannot be in the output. I need to solve both of these to produce an output file in the correct format.
Windows 11, Visual Studio 2022 17.6.5, Intel Fortran (ifort) 2023.2.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note that SEQUENCE promises only not to reorder the components - it says nothing about packing. Whether a compiler packs SEQUENCE types or not is implementation-dependent.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have solved both problems.
The Fortran type is "packed" when I both make the type a BIND(C) type AND bracket the type declaration with !DIR$ OPTIONS /NOALIGN ... !DIR$ END OPTIONS (Steve Lionel's suggestions).
The output file format from
OPEN(UNIT = ioXLI, FILE = TRIM(path), FORM = 'unformatted', ACCESS = 'stream', status = 'replace')
inserts unwanted 4-byte "record lengths", but
OPEN(UNIT = ioXLI, FILE = TRIM(path), FORM = 'binary', ACCESS = 'stream', status = 'replace')
does not. In other words, the FORM = 'binary' causes an unformatted write to behave like a C++ stream, as desired.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note that SEQUENCE promises only not to reorder the components - it says nothing about packing. Whether a compiler packs SEQUENCE types or not is implementation-dependent.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page