Are data structures always contiguous?

Are data structures always contiguous?

Does anyone know if a data structure such as the one below is always contiguous in memory? I can't quite tell from the documentation.

   INTEGER*4  IntArray(10)
   REAL*8  FltArray(23)
   CHARACTER  String*100
   INTEGER*4  Flag

RECORD /Fred/ MyStructure(12)

I have tried adding the CONTIGUOUS attribute to my declaration but the compiler doesn't like it and so I am assuming that it is always contiguous.

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

If the compiler doesn't like contiguous here, I would assume it's because it's unable to avoid padding, or because you have a conflict between legacy non-standard extensions and later standard features.

I think it would be reasonable to interpret the ABI requirements such that both the integer and real*8 arrays must be 16-byte aligned.   I wouldn't be surprised if the documentation doesn't cover this mixture of non-standard syntax.

First of all, the CONTIGUOUS attribute does not instruct the compiler to make something contiguous. Rather, it is used on pointers and assumed-shape dummy arguments to promise the compiler that the object is indeed contiguous. It is not applicable to your case.

The compiler may or may not insert padding into that structure depending on compiler options and other directives in the source. The default is to not insert padding. My advice would be to use the Fortran 2003 TYPE declaration with BIND(C) - that will specify the exact layout, rather than relying on extensions and default behaviors.

Retired 12/31/2016

Have you tried using a derived type instead of a structure? The documentation tells me that CONTIGUOUS works with a derived type, while it says nothing about use with a structure.

Note that a derived type is simply the "official" modern incarnation of the structure, which was a vender-dependent extension used with Fortran 77. Intel still maintains it for compatibility (Intel people, please correct me if I'm wrong on this).

I need the data structure to be contiguous because I like to use the ZeroMemory Windows API to initialize it at various locations in my code just before I reload parts of it with data using something like the following:

CALL ZeroMemory(loc(MyStructure), SizeOf(MyStructure))
Load selected variables of MyStructure with data... 

I use ZeroMemory so that I don't have to set every element of the data structure to NULL individually. If the data structure is not contiguous then I am assuming that ZeroMemory would cause problems.

I am gradually converting my STRUCTURE declarations to TYPE declarations, however I assumed that my contiguous question would apply equally to them also.

If I use a STRUCTURE or TYPE declaration and do nothing else to it, is it contiguous in memory? Note that I am using the /align:rec1byte to remove padding for other reasons.


In the absence of allocatable or pointer components (and perhaps one day length type parameters), and if the array being declared is not a pointer or assumed shape dummy argument - yes, practically.  More so even, if the type is a sequence type.

Note that zeroing the memory of a character component isn't the same as assigning a zero length string to the component.

If someone does pop an allocatable component into the type one day, then the ZeroMemory approach is going to cause serious runtime issues.

Are you familiar with default initialization?  When combined with structure constructors that would let you achieve better brevity and clarity of source at the point of use, without needing to use extensions to the standard.

PROGRAM UnderConstruction
  TYPE Fred
    INTEGER :: IntArray(10) = 0
    REAL :: FltArray(23) = 0.0
    CHARACTER(100) :: String = ''
    INTEGER :: Flag = 0
  TYPE(Fred) :: a
  TYPE(Fred) :: b(5)
  a = Fred()
  a%IntArray(2) = 10
  PRINT "('After setting to some value: ',*(I0,:,1X))", a%IntArray
  a = Fred()
  PRINT "('After (re)construction: ',*(I0,:,1X))", a%IntArray
  b = Fred(Flag=1)    ! All b's have a Flag of 1.
  b(2)%Flag = 9       ! Now element 2 is special.
  PRINT "('After setting to some value: ',*(I0,:,1X))", b%Flag
  b = Fred()
  PRINT "('After (re)construction: ',*(I0,:,1X))", b%Flag
END PROGRAM UnderConstruction

CONTIGUOUS simply means that there is no spacing between array elements. It has no effect on layout of a structure or derived type. It is applicable only to an array pointer or assumed-shape array.

BIND(C) for a derived type is better than SEQUENCE here. SEQUENCE simply prevents the compiler from rearranging components, not that Intel Fortran does that. It doesn't necessarily prevent padding, though by default we won't pad a SEQUENCE type. BIND(C) types are better in that the standard specifies what the layout should be, though if the "companion C processor" would add padding, so would Fortran.

We do have directives such as !DIR$ OPTIONS /NOALIGN that can be used to disable alignment padding no matter what compiler options were specified.

Retired 12/31/2016

Thanks, that clarifies it.

My problem is that I need to maintain my source code for an old Watcom Fortran compiler as well as the latest Intel one, and I'm trying to avoid having thousands of #ifdef's as much as possible. It should be smooth sailing once I've weened off the old compiler.

Leave a Comment

Please sign in to add a comment. Not a member? Join today