Previous: STRUCTURE and RECORD, Up: Extensions implemented in GNU Fortran


6.1.21 UNION and MAP

Unions are an old vendor extension which were commonly used with the non-standard STRUCTURE and RECORD extensions. Use of UNION and MAP is automatically enabled with -fdec-structure.

A UNION declaration occurs within a structure; within the definition of each union is a number of MAP blocks. Each MAP shares storage with its sibling maps (in the same union), and the size of the union is the size of the largest map within it, just as with unions in C. The major difference is that component references do not indicate which union or map the component is in (the compiler gets to figure that out).

Here is a small example:

     structure /myunion/
     union
       map
         character(2) w0, w1, w2
       end map
       map
         character(6) long
       end map
     end union
     end structure
     
     record /myunion/ rec
     ! After this assignment...
     rec.long = 'hello!'
     
     ! The following is true:
     ! rec.w0 === 'he'
     ! rec.w1 === 'll'
     ! rec.w2 === 'o!'

The two maps share memory, and the size of the union is ultimately six bytes:

     0    1    2    3    4   5   6     Byte offset
     -------------------------------
     |    |    |    |    |    |    |
     -------------------------------
     
     ^    W0   ^    W1   ^    W2   ^
      \-------/ \-------/ \-------/
     
     ^             LONG            ^
      \---------------------------/

Following is an example mirroring the layout of an Intel x86_64 register:

     structure /reg/
       union ! U0                ! rax
         map
           character(16) rx
         end map
         map
           character(8) rh         ! rah
           union ! U1
             map
               character(8) rl     ! ral
             end map
             map
               character(8) ex     ! eax
             end map
             map
               character(4) eh     ! eah
               union ! U2
                 map
                   character(4) el ! eal
                 end map
                 map
                   character(4) x  ! ax
                 end map
                 map
                   character(2) h  ! ah
                   character(2) l  ! al
                 end map
               end union
             end map
           end union
         end map
       end union
     end structure
     record /reg/ a
     
     ! After this assignment...
     a.rx     =     'AAAAAAAA.BBB.C.D'
     
     ! The following is true:
     a.rx === 'AAAAAAAA.BBB.C.D'
     a.rh === 'AAAAAAAA'
     a.rl ===         '.BBB.C.D'
     a.ex ===         '.BBB.C.D'
     a.eh ===         '.BBB'
     a.el ===             '.C.D'
     a.x  ===             '.C.D'
     a.h  ===             '.C'
     a.l  ===               '.D'