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

Q115851

7.00 | 1.00 MS-DOS | WINDOWS kbtool kbfixlist kbbuglist ---------------------------------------------------------------------- The information in this article applies to: - The Microsoft C/C++ Compiler (CL.EXE), included with: - Microsoft C/C++ for MS-DOS, version 7.0 - Microsoft Visual C++ for Windows, version 1.0 ---------------------------------------------------------------------- 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
Issue type :
Technology : kbVCsearch kbAudDeveloper kbCVCComp


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