Alignment (The GNU Modula-2 Compiler)

### 2.19 Data type alignment ¶

GNU Modula-2 allows you to specify alignment for types and variables. The syntax for alignment is to use the ISO pragma directives `<*` `bytealignment (` expression `)` and `*>`. These directives can be used after type and variable declarations.

The ebnf of the alignment production is:

    Alignment := [ ByteAlignment ] =:
    ByteAlignment := '<*' AttributeExpression '*>' =:
    AlignmentExpression := "(" ConstExpression ")" =:

The `Alignment` ebnf statement may be used during construction of types, records, record fields, arrays, pointers and variables. Below is an example of aligning a type so that the variable `bar` is aligned on a 1024 address.

    MODULE align ;

    TYPE
       foo = INTEGER <* bytealignment(1024) *> ;

    VAR
       z  : INTEGER ;
       bar: foo ;
    BEGIN
    END align.

The next example aligns a variable on a 1024 byte boundary.

    MODULE align2 ;

    VAR
       x  : CHAR ;
       z  : ARRAY [0..255] OF INTEGER <* bytealignment(1024) *> ;
    BEGIN
    END align2.

Here the example aligns a pointer on a 1024 byte boundary.

    MODULE align4 ;

    FROM SYSTEM IMPORT ADR ;
    FROM libc IMPORT exit ;

    VAR
       x  : CHAR ;
       z  : POINTER TO INTEGER <* bytealignment(1024) *> ;
    BEGIN
       IF ADR(z) MOD 1024=0
       THEN
          exit(0)
       ELSE
          exit(1)
       END
    END align4.

In example `align5` record field `y` is aligned on a 1024 byte boundary.

    MODULE align5 ;

    FROM SYSTEM IMPORT ADR ;
    FROM libc IMPORT exit ;

    TYPE
       rec = RECORD
                x: CHAR ;
                y: CHAR <* bytealignment(1024) *> ;
             END ;
    VAR
       r: rec ;
    BEGIN
       IF ADR(r.y) MOD 1024=0
       THEN
          exit(0)
       ELSE
          exit(1)
       END
    END align5.

In the example below module `align6` declares `foo` as an array of 256 `INTEGER`s. The array `foo` is aligned on a 1024 byte boundary.

    MODULE align6 ;

    FROM SYSTEM IMPORT ADR ;
    FROM libc IMPORT exit ;

    TYPE
       foo = ARRAY [0..255] OF INTEGER <* bytealignment(1024) *> ;

    VAR
       x  : CHAR ;
       z  : foo ;
    BEGIN
       IF ADR(z) MOD 1024=0
       THEN
          exit(0)
       ELSE
          exit(1)
       END
    END align6.