Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29282 Discussions

Unformatted write of derived type which is not aligned

AONym
New Contributor II
1,355 Views

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.

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
1,182 Views

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.

View solution in original post

3 Replies
AONym
New Contributor II
1,317 Views

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.

jimdempseyatthecove
Honored Contributor III
1,281 Views

There is also SEQUENCE.

Jim

0 Kudos
Steve_Lionel
Honored Contributor III
1,183 Views

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.

Reply