FIX: /Ow Generates Bad Code When Using the

ID: Q114071

1.00 WINDOWS kbtool kbfixlist kbbuglist

The information in this article applies to:

SYMPTOMS

When using the /Ow and /AL compiler switches to compile code that uses the left shift operator (<<) on an address prior to assigning it to a variable, the compiler does not generate the proper instructions when the address of that variable is later assigned to another variable.

RESOLUTION

To avoid the problem, either do not use the left shift operator in the address assignment, or disable the /Ow optimization. This can be done by either not using the /Ow option on the command line, or by using #pragma optimize to disable the optimization in the source file. The comments in the sample below demonstrate using #pragma optimize statements to work around the problem.

STATUS

Microsoft has confirmed this to be a problem in C/C++ for MS-DOS version 8.0. This problem was corrected in C/C++ for MS-DOS version 8.0c, included with Visual C++ for Windows, version 1.5.

MORE INFORMATION

The sample code below can be used to reproduce the problem. When using /Ow and the << operator, the following incomplete assembly instructions are generated for the last line of code in the example:

; Line 25

     mov     WORD PTR es:16,cx
     mov     WORD PTR es:18,es

When either the /Ow optimization or the left shift operator (<<) is removed, the compiler correctly generates the following proper instructions:

; Line 25

     lea     cx,WORD PTR es:4
     mov     WORD PTR es:16,cx
     mov     WORD PTR es:18,es

Sample Code

/* Compile options needed: /c /AL /Ow
*/ 

typedef struct node {
    long data;
    struct node *next;
    struct node *prev;
} NODE;

typedef struct list {

    struct list *next;
    NODE head;
    NODE *tail;
} LIST;

// Uncomment for work around
// #pragma optimize ("w", off)

void Init( unsigned long addr )
{
    LIST *pList;

    pList = (LIST *)(addr << 16);
    pList->next = (void *)0L;
    pList->head.data = 0L;
    pList->head.next = (void *)0L;
    pList->head.prev = (void *)0L;
    pList->tail = &pList->head;
}

// Uncomment for work around
// #pragma optimize ("", on)

Additional reference words: 1.00 8.00 KBCategory: kbtool kbfixlist kbbuglist KBSubcategory: CLIss
Keywords          : kb16bitonly kbCompiler kbbuglist kbfixlist
Version           : 1.00
Platform          : WINDOWS
Solution Type     : kbfix

Last Reviewed: September 22, 1997