## FIX: /Ow Generates Bad Code When Using the

Q114071

    1.00
    WINDOWS
    kbtool kbfixlist kbbuglist

    ----------------------------------------------------------------------
    The information in this article applies to:

     - The Microsoft C/C++ Compiler (CL.EXE), included with:
        - Microsoft Visual C++ for Windows, version 1.0
    ----------------------------------------------------------------------

    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
Issue type :
Technology : kbVCsearch kbAudDeveloper kbCVCComp

Last Reviewed: May 5, 2001 © 2001 Microsoft Corporation. All rights reserved. Terms of Use.