Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is unevaluated division by 0 undefined behavior?

I'm having a disagreement with some co-workers over the following code:

int foo ( int a, int b ) {     return b > 0 ? a / b : a; } 

Does this code exhibit undefined behavior?

EDIT: The disagreement started from what appears to be a bug in an overly-eager optimizing compiler, where the b > 0 check was optimized out.

like image 667
Luchian Grigore Avatar asked Oct 21 '16 09:10

Luchian Grigore


People also ask

Is Division by zero undefined behavior?

Regarding division by zero, the standards say: C99 6.5. 5p5 - The result of the / operator is the quotient from the division of the first operand by the second; the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined.

What happens if you divide by zero in C?

C Language Undefined behavior Division by zero Note that most implementations of floating point math will follow a standard (e.g. IEEE 754), in which case operations like divide-by-zero will have consistent results (e.g., INFINITY ) even though the C standard says the operation is undefined.

Why does C have undefined behavior?

So, in C/C++ programming, undefined behavior means when the program fails to compile, or it may execute incorrectly, either crashes or generates incorrect results, or when it may fortuitously do exactly what the programmer intended.


1 Answers

No.


Quotes from N4140:

§5.16 [expr.cond]/1

Conditional expressions group right-to-left. The first expression is contextually converted to bool. It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. Only one of the second and third expressions is evaluated.

Further:

§5 [expr]/4

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

This clearly does not happen here. The same paragraph mentions division by zero explicitly in a note, and, although it is non-normative, it's making it even more clear that its pertinent to this situation:

[ Note: most existing implementations of C++ ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and all floating point exceptions vary among machines, and is usually adjustable by a library function. —end note ]


There's also circumstantial evidence reinforcing the above point: the conditional operator is used to conditionally make behavior undefined.

§8.5 [dcl.init]/12.3

int f(bool b) {   unsigned char c;   unsigned char d = c; // OK, d has an indeterminate value   int e = d; // undefined behavior   return b ? d : 0; // undefined behavior if b is true } 

In the above example, using d to initialize int (or anything other than unsigned char) is undefined. Yet it is clearly stated that the UB occurs only if the UB branch is evaluated.


Going out of language-lawyer perspective: if this could be UB, then any division could be treated as UB, since the divisor could potentially be 0. This is not the spirit of the rule.

like image 100
krzaq Avatar answered Sep 21 '22 17:09

krzaq