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:
- BLUE for XTRAN versions (runnable programs)
- ORANGE for XTRAN rules (text files)
- RED for
code - PURPLE for text data files
Input to XTRAN:
typedef struct str1_t { float str1_t_m1; short str1_t_m2[5]; } Str1_t; struct str2_t { long str2_t_m1[3]; short str2_t_m2; Str1_t str2_t_m3[2]; }; struct { short str1_m1[2]; struct str2_t str1_m2[3]; Str1_t str1_m3; struct { short str1_m4_m1; char str1_m4_m2[2]; } str1_m4; union { short str1_m5_m1; char str1_m5_m2[4]; } str1_m5; float str1_m6[4]; double str1_m7; } str1;
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