If a structure will be referenced in both 32-bit and 16-bit code and contains bit-fields or members of type int or enum, you may have to rewrite the structure to ensure that all members align properly.
To use Microsoft C Version 6.0 long double data under IBM C and C++ Compilers, you must recompile it on the Microsoft C Version 6.0 compiler as double first, and place into into a struct to pad out to 128 bits. Although IBM C and C++ Compilers and Microsoft C Version 6.0 both store long double as 80 bit real, IBM C and C++ Compilers stores it in a 16 byte (128 bit) field.
The size of type enum differs between compilers. For example, the IBM C/2 makes all enum types 2 bytes, while IBM C and C++ Compilers defines the size as 1, 2, or 4 bytes, depending on the range of values the enumeration contains.
You can use the /Su compiler option to force IBM C and C++ Compilers to make the enum type 1,2, or 4 bytes, or to use the SAA rules that make all enum types the size of the smallest integral type that can contain all variables.
struct s1 { /* Compatible */ (1)
int a : 4;
int b : 7;
int c : 5;
};
struct s2 { /* Not compatible */ (2)
int z : 9;
int y : 12;
};
(1) Because the type of the bit field members is int, Microsoft C Version 6.0 will allocate 16 bits' (sizeof(int)) of space in the struct to store the bit field.
There are 16 bits of bit fields declared in the declaration of s1, so the bit fields are packed tightly.
IBM C and C++ Compilers allocates 2 bytes for the bit field, and is compatible with Microsoft C Version 6.0 as they lay out the bit field in precisely the same way.
(2) There is not enough room in the 16-bit int to store the first two members of s2, so Microsoft C Version 6.0 introduces 7 bits of padding to made the member z fill out an entire int. It introduces an additional 4 bits of padding after y to fill up the last byte. This bit field requires 4 bytes of storage using Microsoft C Version 6.0, but only 3 bytes using IBM C and C++ Compilers. Therefore, the padding introduced by the compiler makes the bit fields incompatible.
Compilers using 16-bit format align these types on 1-byte boundaries.
IBM C and C++ Compilers aligns members of type int, long, float, double, long double, and pointer on 4-byte boundaries.
If the pointer is passed directly as a parameter, the compiler automatically converts it to a 16-bit pointer and the _Seg16 keyword is not required. For example, the declaration
void _Far16 _cdecl foo(char *);
is equivalent to
void _Far16 _cdecl foo(char * _Seg16);
It is good programming style to explicitly declare pointer parameters in 16-bit function prototypes as being _Seg16.
If your pointers are used primarily as parameters to 16-bit functions and are not used extensively in your 32-bit code, it may be better to declare them with _Seg16.
Use the _Seg16 qualifier only when necessary. Because of the conversions that are performed whenever a _Seg16 pointer is used in 32-bit code, unnecessary use of segmented pointers can cause a noticeable degradation in application performance.
![]()
Call Between 32-bit and 16-bit
Code