PRB: /Zp4 Cannot Be Used with Some C Run-time Header Files

ID Number: Q73849

5.10 6.00 6.00a 6.00ax | 5.10 6.00 6.00a

MS-DOS | OS/2

buglist5.10 buglist6.00 buglist6.00a buglist6.00ax fixlist7.00

Summary:

SYMPTOMS

The C compiler option /Zp4 (pack structures to 4 bytes) cannot be

used with some Microsoft C run-time header files. For example,

using /Zp4 with STDIO.H in the large memory model (/AL) results in

problems with the standard stream handles (stdin, stdout, stdaux,

stderr, stdprn). This is a problem with Microsoft C versions 5.1,

6.0, 6.0a, and 6.0ax and QuickC versions 2.0, 2.01, 2.0, and 2.51.

Header files with structures that cannot be used with /Zp4 include

DOS.H, EXT.H, MATH.H, STAT.H, STDIO.H, and the OS/2 header files.

The sample program below illustrates this problem.

RESOLUTION

To work around this problem, compile the header file with packing

set to 1 or 2 bytes. This can be done by placing #pragma pack(2)

just before the #include directive. After the include file is

compiled, packing can be set back to 4 bytes again with #pragma

pack(4) placed after the #include directive. The comments in the

sample code illustrates this workaround. If the pragmas are

uncommented, the program will run successfully even if compiled

with /Zp4.

STATUS

Microsoft has confirmed this to be a problem in C versions 5.1,

6.0, 6.0a, and 6.0ax and QuickC versions 2.0, 2.01, 2.5, and 2.51

(buglist2.00, buglist2.01 buglist2.50, and buglist2.51). This

problem was corrected in C/C++ version 7.0.

More Information:

The C header files must be compiled with packing set to 1 or 2 bytes

because there are structures declared inside the header files, and the

compiler generates code for accessing these structures based on the

packing. On the other hand, the library functions are compiled using

default packing, and any structure access by the library code will be

based on the default packing amount. Default structure packing is /Zp1

in C 5.1, and /Zp2 in C 6.0, 6.0a, and 6.0ax and QuickC 2.0, 2.1, 2.5,

and 2.51.

The standard stream handles mentioned above further illustrate this.

The structure FILE is declared inside STDIO.H, but storage for the

streams is not allocated. The stdin...stderr streams are assigned to

an external array of stream file handles that were previously compiled

inside the combined library with /Zp2 (the default). Thus, using /Zp4

on STDIO.H creates a situation where you are linking two objects with

different packing options, and the code will fail.

Sample Code

-----------

/* Compile options needed: /Zp4 /AL

*/

// Uncomment the following pragmas to eliminate the packing problem.

//#pragma pack(2)

#include <stdio.h>

//#pragma pack(4)

#include <conio.h>

void main(void)

{

fprintf(stderr,"\nThis line should be displayed\n\n");

getch();

}

Additional reference words: 2.00 2.50 5.10 6.00 6.00a 6.00ax