FIX: Use of /Oe with Ternary Operator May Generate Bad Code

ID: Q115851

7.00 | 1.00 MS-DOS | WINDOWS kbtool kbfixlist kbbuglist

The information in this article applies to:

SYMPTOMS

The compiler may generate bad code when the /Oe compiler optimization switch is used when compiling code that contains a complex use of the conditional (ternary) operator. The sample code below shows one such case.

CAUSE

This problem is due to an overly aggressive code generation technique which lengthens byte memory references to word memory references in certain cases.

RESOLUTION

You can correct this error by either

1. removing the /Oe switch

   -or-

2. disabling the optimization via the #pragma statement

   -or-

3. simplifying the statement containing the conditional operator

STATUS

Microsoft has confirmed this to be a problem in the C/C++ compiler for MS-DOS, versions 7.0 and 8.0. This problem was corrected in the C/C++ compiler for MS-DOS version 8.0c, which is included in Visual C++ for Windows, version 1.5.

MORE INFORMATION

The following is a fragment of the assembly code generated when compiling the sample code below:

   *** 00001d  26 ff 07          inc   WORD PTR es:[bx]
   *** 000020  26 8e 47 02       mov   es,WORD PTR es:[bx+2]
   *** 000024  26 8b 34          mov   si,WORD PTR es:[si]

The last line of this assembly language fragment is incorrect. The correct assembly language for this would be:

      *** 000021  26 ff 07          inc   WORD PTR es:[bx]
      *** 000024  26 8e 47 02       mov   es,WORD PTR es:[bx+2]
      *** 000028  26 8a 04          mov   al,BYTE PTR es:[si]

Sample Code

/*  compile with these switches: -c -Oe -Fc
*/ 

struct mystruct {
      unsigned char  _far  *ptr;
      int (*buf)(mystruct _far *);
      short cnt;
};

// #pragma optimize ("e",off)    // Uncomment line to fix problem
void func1(void)
{
      int c;
      mystruct _far *fb = (mystruct far *)0;

      while ((c = (--(fb)->cnt>=0 ?
        ((int)(*((fb)->ptr)++)) : (*(fb)->buf)(fb))) != (-1));
}
// #pragma optimize ("e", on)

void main()
{
  func1();
}

Additional reference words: 1.00 7.00 8.00 register KBCategory: kbtool kbfixlist kbbuglist KBSubcategory: CodeGen

Keywords          : kb16bitonly kbCodeGen kbbuglist kbfixlist
Version           : 7.00   | 1.00
Platform          : MS-DOS WINDOWS
Solution Type     : kbfix

Last Reviewed: September 22, 1997