[comp.sys.ibm.pc] Problems with Quick C v 2

LC.YRS@forsythe.stanford.edu (Richard Stanton) (09/27/89)

Here are two problems I recently encountered with Microsoft Quick C
v 2.0, one of which is a bug, and one of which is not. The lessons I
learned may be of value to other people.

1) Here is a little program called TEST.C:

#include <stdio.h>

main()
{
        int i,j,k;

        for(i=0; i<3; i++) {
                printf("Starting it. %4d\n",i);
                for(j=0; j<3; j++) {
                        for(k=0; k<3; k++) {
                                printf("%4d %4d %4d\n",i,j,k);
                        }
                }
        }
        return 0;
}

Compiled under Quick C v 2.0, using the command

        QCL test.c

this program gave the (correct) results:

Starting it.    0
   0    0    0
   0    0    1
   0    0    2
   0    1    0
   0    1    1
   0    1    2
   0    2    0
   0    2    1
   0    2    2
Starting it.    1
   1    0    0
   1    0    1
   1    0    2
   1    1    0
   1    1    1
   1    1    2
   1    2    0
   1    2    1
   1    2    2
Starting it.    2
   2    0    0
   2    0    1
   2    0    2
   2    1    0
   2    1    1
   2    1    2
   2    2    0
   2    2    1
   2    2    2

However, when compiled with loop optimization on, using the command

        QCL /Ol test.c          (or QCL /Ox test.c)

the following happened:

Starting it.    0
   0    0    0
   1    0    1
   2    0    2
   0    1    0
   1    1    1
   2    1    2
   0    2    0
   1    2    1
   2    2    2

It took me several hours to realize that the problem was with Quick C,
and not with my original, much larger, program. The solution is simple -
NEVER use loop optimization with Quick C v 2.0. Microsoft confirm that other
people have noticed problems with this, but they do not expect to do anything
about it until the next release.

2) Here is a scrap of a program called CHKFRAG.C, from PC Magazine:

struct  bootrec
        {
        char jmp[3],                    /* jump instruction             */
             oem[8];                    /* OEM name                     */
        UINT bytes;                     /* bytes per sector             */
        char cluster;                   /* sectors per cluster          */
        UINT res_sectors;               /* reserved sectors             */
        char fats;                      /* number of fats               */
        UINT roots,                     /* number of root dir entries   */
             sectors;                   /* total sectors                */
        char media;                     /* media descriptor block       */
        UINT fatsize,                   /* sectors per fat              */
             tracksize,                 /* sectors per track            */
             heads,                     /* number of heads              */
             hidden;                    /* hidden sectors               */
        } far *b_rec;                   /* boot record definition       */

This looks OK for the boot record, according to my DOS books, but it just
wouldn't work. I finally discovered that Quick C (and MSC) do not
automatically pack structures like this into the smallest possible space. They
default to starting all integers on even bytes, which caused things to
get misaligned. This can be solved by either typing

#pragma pack(1)

before the structure definition, or by compiling with the switch /Zp1.

While this is not a bug, it took me a while to work out what was
going on.

I hope this helps somebody else avoid wasting their time
over the same problems.

Richard Stanton