PRB: Post-Incrementation May Differ if Compile with /qc or /f

Last reviewed: July 17, 1997
Article ID: Q81886
6.00 6.00a 6.00ax 7.00 | 6.00 6.00a | 1.00 1.50
MS-DOS                 | OS/2       | WINDOWS
kbprg kbprb

The information in this article applies to:

  • Microsoft C for MS-DOS, versions 6.0, 6.0a, and 6.0ax
  • Microsoft C for OS/2, versions 6.0 and 6.0a
  • Microsoft C/C++ for MS-DOS, version 7.0
  • Microsoft Visual C++ for Windows, versions 1.0 and 1.5

SYMPTOMS

Post-incrementation sometimes gives unexpected results when it is used in code where the precedence of that operation over others is undefined by the ANSI standard. The results may differ between different versions of the compiler as well as between the same version of the compiler using different switches.

The symptoms resulting from the differences in generated code may be difficult to determine because a variety of effects can be produced. In general, if code compiled with and without the /qc or /f option generates different results, ambiguous precedence involving post-incrementation may be the cause. For example, code may work as desired when compiled with /qc or /f, and corrupt memory when compiled without /qc or with /f-, if pointers are being post-incremented.

Note that this discussion also applies to pre-incrementation, pre- decrementation, and post-decrementation.

CAUSE

Section 3.3 of the ANSI draft states that:

   Between the previous and next sequence point an object shall
   have its stored value modified at most once by the evaluation
   of an expression. Furthermore, the prior value shall be accessed
   only to determine the value to be stored (31).

       .
       .
       .

   (31)  This paragraph renders undefined statement expressions
         such as

            i = ++i + 1;
         while allowing

            i = i + 1;

Therefore, the behavior is implementation-dependent, and will vary from compiler to compiler.

When the Microsoft C compiler is invoked with the /qc or /f option, the fast compiler is used which handles ambiguous precedence involving post-incrementation differently than the optimizing compiler.

RESOLUTION

Generally, code should be written so as not to be ambiguous by the ANSI standard. This ensures that the code is portable to any ANSI C compiler.

If it is not possible to eliminate the ambiguous code, then it must be compiled with the compiler that gives the desired result.

MORE INFORMATION

The following line of code can be used to demonstrate how the implementations differ:

   for ( i=0; array[i] != '\0'; ptr[i]=array[i++] );

If compiled with /qc or QuickC, it is evaluated as if it were:

   for ( i=0; array[i] != '\0'; ptr[i+1]=array[i], i++ );

If compiled without /qc, it is evaluated as if it were:

   for ( i=0; array[i] != '\0'; ptr[i]=array[i], i++ );


Additional reference words: 6.00 6.00a 6.00ax 7.00 1.00 1.50
KBCategory: kbprg kbprb
KBSubcategory: CLngIss
Keywords : kb16bitonly


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 17, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.