BUG: C Compiler May Not Catch Integer Division-by-Zero Error

Last reviewed: September 12, 1997
Article ID: Q72889
The information in this article applies to:
  • The Microsoft C/C++ Compiler (CL.EXE) included with - Microsoft C for MS-DOS, versions 6.0, 6.0a, 6.0ax - Microsoft C/C++ for MS-DOS, version 7.0 - Microsoft Visual C++ for Windows, versions 1.0, 1.5 - Microsoft Visual C++ 32-bit Edition, versions 1.0, 2.0, 2.1, 4.0, 4.1,

         5.0
    

SYMPTOMS

The Microsoft C/C++ compilers listed above may fail to detect a constant expression that will cause a divide-by-zero error. In these situations, the Microsoft C compiler version 6.xx may ignore the error entirely and instead use the value zero for the expression. The Microsoft C/C++ compiler version 7.0 and those included with all versions of Visual C++ may not generate an error at compile-time, but the resulting application should produce a run-time error, either on the command line as

   error R6003: integer divide by 0

or in an Application Error message window (dialog box) with the text

   The exception Integer division by zero
   (<hex value>) occurred in the application at location <hex address>.

CAUSE

The Microsoft C Compiler version 6.xx does not correctly handle constant propagation in all cases where optimizations are performed. Thus, when it evaluates constant expressions, it may not detect a divide-by-zero error, but instead use zero as the result of the expression. This, in turn, precludes any run-time errors.

The Microsoft C/C++ compiler version 7.0 and those included with all versions of Visual C++ handle the evaluation of constant expressions differently than does the Microsoft C Compiler version 6.xx. Although it may not detect a divide-by-zero error, it doesn't necessarily perform constant propagation for expressions depending upon a division operation. This allows the operation to be executed at run-time and the divide-by-zero error to be trapped.

RESOLUTION

To work around the problem in C 6.0, you must declare the code in such a way as to disable the constant propagation optimization of the compiler. This will ensure that the division takes place at run time and then the divide-by-zero interrupt may occur. The following are methods to do this:

  • Use /Od to disable all optimizations.

    -or-

  • Use the optimize pragma to turn off "c" optimization.

    -or-

  • Compile with the /qc (quick compile) option.

    -or-

  • Declare any variable that will become a divisor as "volatile."

To work around the problem with all compilers listed above, you should
  • redefine your code such that zero is never used as a denominator.

    -or-

  • provide in-code checks for denominators that equal zero such that afflicted expressions may be avoided.

STATUS

Microsoft has confirmed this to be a problem in the products listed at the beginning of this article. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

Because dividing by 0 (zero) results in an undefined value, the Intel chip issues a specific interrupt (Int 0) to trap this error. This interrupt can, in turn, be processed by an application in an appropriate manner. By default, the Microsoft run-time libraries install an interrupt handler. When interrupted by a divide-by-zero error, this handler either writes a message to stdout or activates an Application Error message box and then, in both cases, terminates the program.

When an expression in a source file can be evaluated to a constant, the compiler may "precalculate" the value and then, at run time, the result is simply loaded into the destination. This process is called "constant propagation." Because this constant propagation performed by the compiler handles the evaluation of the expression at compile time, the generated code does not contain any arithmetic instructions for that particular expression. Instead, the generated code just contains an instruction to load the result.

In the case where an expression can be predetermined to cause a divide-by- zero error (because a divisor evaluates to zero), the compiler should trap the error during compilation of the source module and generate the following error:

   error C2124: divide or mod by zero

This is important because the elimination of the division from the generated code means that a run-time error will not be generated.

The Microsoft C Compiler version 6.xx may not generate the C2124 error. This means that a divide-by-zero error may be occurring which is not detected at compile time, and the optimization prevents it from being detected at run time. Instead, the compiler uses the value zero as the result.

The program example below illustrates this problem. The Microsoft C Compiler version 6.xx generates code to load a zero at run time instead of generating an error message indicating that a possible division by zero is going to be performed. As described above, this also prevents a R6003 error from being generated at run time. The Microsoft C/C++ compiler version 7.0 and all versions included with Visual C++ generate code that performs a division by zero at run-time. The error is trapped and the user is informed appropriately.

Sample Code

   /* Compile options needed: none
   */

   #include <stdio.h>

   void main( void)
   {
      int a = 5;
      int b = 0;            // Declare as volatile for workaround

      a = a / b;

      printf( "a/b = %d\n", a);
   }


Additional query words: 8.00 8.00c 9.00 10.00 10.10
Keywords : CLIss vcbuglist500
Version : 6.0 6.0a 6.0ax 7.0 1.0 1.5 2.0 2
Platform : MS-DOS NT WINDOWS
Issue type : kbbug


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: September 12, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.