XTRAN Example — Analyze Structure/Union Member Offsets in C, C++, Java, or C#

It is often desirable to know the offsets to various fields in a data area, and those fields' sizes, especially when such an area is declared a number of different ways.  An example would be a shared common in a real-time system that is declared in both assembler and a 3GL.

The following example uses an XTRAN rules file comprising just under 140 non-comment lines of XTRAN's rules language ("meta-code") to analyze C, C++, Java, or C# code to determine the offset to, and size of, each structure and/or union member.  The XTRAN rules themselves are not particularly specific to C / C++ / Java / C#; they can be easily adapted to analyze any 3GL language that allows structures and/or unions.

Note that the analysis output shows each member's offset on the left, and shows the size of each structure, union, and member.  Also, notice that the analysis shows, for each union, the size of the union's largest member.

These rules were used in an actual migration project to verify that two declarations of a shared common area were equivalent.  One version was translated from VAX assembler to C, and the other was originally coded in C.  The layout of the area included several hundred members, including nested structures and unions.

The input to and output from XTRAN are untouched.

Process Flowchart

Here is a flowchart for this process, in which the elements are color coded:

data flowchart

Input to XTRAN:

	typedef struct str1_t
	    float str1_t_m1;
	    short str1_t_m2[5];

	struct str2_t
	    long str2_t_m1[3];
	    short str2_t_m2;
	    Str1_t str2_t_m3[2];

	    short str1_m1[2];
	    struct str2_t str1_m2[3];
	    Str1_t str1_m3;
	        short str1_m4_m1;
		char str1_m4_m2[2];
		} str1_m4;
	        short str1_m5_m1;
		char str1_m5_m2[4];
		} str1_m5;
	    float str1_m6[4];
	    double str1_m7;

Output from XTRAN:

                    Structure/union member offsets & sizes

     0 Str1_t = 14
     0     str1_t_m1 = 4
     4     str1_t_m2 = 10

     0 struct str2_t = 42
     0     str2_t_m1 = 12
    12     str2_t_m2 = 2
    14     str2_t_m3 = 28

     0 str1 = 176
     0     str1_m1 = 4
     4     str1_m2 = 126
   130     str1_m3 = 14
   144     str1_m4 = 4
   144         str1_m4_m1 = 2
   146         str1_m4_m2 = 2
   148     str1_m5 = 4
   148         str1_m5_m1 = 2
   148         str1_m5_m2 = 4
   152     str1_m6 = 16
   168     str1_m7 = 8