Microsoft KB Archive/72889

{|
 * width="100%"|

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

 * }

Q72889

-

The information in this article applies to:


 * 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
 * Microsoft Visual C++ for Windows, versions 1.0, 1.5
 * Microsoft Visual C++, 32-bit Editions, versions 1.0, 2.0, 2.1, 4.0, 4.1, 5.0, 6.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 occurred in the application at location.

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 &quot;c&quot; optimization.

-or-
 * Compile with the /qc (quick compile) option.

-or-
 * Declare any variable that will become a divisor as &quot;volatile.&quot;

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 bug in the Microsoft products listed at the beginning of this article.

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 &quot;precalculate&quot; the value and then, at run time, the result is simply loaded into the destination. This process is called &quot;constant propagation.&quot; 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 

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

a = a / b;

printf( &quot;a/b = %d\n&quot;, a); } Additional query words: 8.00 8.00c 9.00 10.00 10.10

Keywords : kbCompiler kbVC100bug kbVC200bug kbVC210bug kbVC400bug kbVC410bug kbVC500bug kbVC600bug

Issue type : kbbug

Technology : kbvc