PRB: C 6.x May Not Catch Integer Division-by-Zero Error

ID Number: Q72889

6.00 6.00a 6.00ax | 6.00 6.00a

MS-DOS | OS/2

buglist6.00 buglist6.00a buglist6.00ax

Summary:

SYMPTOMS

The Microsoft C Compiler versions 6.0, 6.0a, and 6.0ax may fail to

detect a constant expression that will cause a divide-by-zero

error. In this case, the compiler should produce the following

error:

error C2124: divide or mod by zero

When the compiler fails to flag this type of error, the generated

code may also prevent a divide-by-zero error from occurring at run

time.

RESOLUTION

To work around the problem, 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."

STATUS

Microsoft has confirmed this to be a problem in C versions 6.0,

6.0a, and 6.0ax. We are researching this problem and will post new

information here as it becomes available.

More Information:

Dividing an integer by 0 (zero) results in an undefined value. In

order to trap this error, the Intel chip issues a specific interrupt

(Int 0), which an application can trap and handle in an appropriate

manner. By default, the Microsoft run-time libraries install an

interrupt handler that prints out the following message to stdout when

a divide-by-zero occurs, and then it terminates the program:

error R6003: integer divide by 0

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 C2124 error. This is important because the

elimination of the division from the generated code means that an

R6003 error cannot be generated at run time.

The Microsoft C Compiler versions 6.0, 6.0a, and 6.0ax do not generate

the C2124 error. This means that a divide-by-zero error may be

occurring that is not detected at compile time, and the optimization

prevents it from being detected at run time. Instead, these compilers

use the value zero as the result. With C version 5.1, the compiler

prints a C2023 error (the previous divide-by-zero error number) and

terminates.

The program example below illustrates this problem. Instead of

generating an error message indicating that a possible division by

zero is going to be performed, the compiler generates code to load a

zero at run time. As described above, this also prevents the R6003

error from being generated at run time.

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 reference words: 6.00 6.00a 6.00ax