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.
return p ? p->flag_value : false
UB whenp
is null? No. All code would be broken if that were the case. – Arelusreturn (p != nullptr && p->flag_value);
. :-) – Ronen? :
and especially in the&&
case. The co-workers might not know that C/C++ behaves in this way or fear that there are compilers which behave non-standard-conforming. – Oakmanint?
orint.MaxValue
in the case of a division by zero. Note in math it's considered a undefined operation. Also don't understand why you cannot divide by negative. – Orthogenicreturn b > 0 ? a / b : a
andif (b > 0) { return a / b; } else { return a; }
? How does your co-worker (judging by your 'apparently...' comment, it is the coworker that thinks there's a problem) donull
value checking before usage, if notreturn (x != null) ? x.Property : [null case value]
norif (x != null) { return x.Property; } else { return [null case value]; }
, nor an equivalent? – Byersint f() { return 1/0; }
exhibits undefined behavior. You must call it to invoke undefined behavior. – Platforma
that you occasionally want to lower, when the function to optimize has some problematic points with strong gradient changes. You might define a step reduction factorb
which in well-behaved cases is <1, but potentially ends up negative. You can then of course define ab_positive = std::max(1,b)
but that is equivalent to the code above. – Lorianneargc > 1
before usingargv[1]
also has UB? If so, avoiding UB would be impossible, and the C standard would be absolutely useless. The UB of division by zero is about evaluated expressions, and because of the sequencing specified for the conditional operator,a / b
is never evaluated whenb == 0
. – Hairstreak