When I have an integer or a pointer a
, it turns out that both
!a
and
a==0
have the same behavior. At a very low level, is there some difference in terms of speed of computation?
It's unlikely there will be a difference in performance, because compilers know about the logical equivalence and so there's no reason they can't emit identical code for both.
The equivalence is elementary, not some clever theorem: the meaning of !a
for integer types defined in the standards is "value of a
equal to 0" (or strictly speaking as James points out, "not (value of a
not 0)"), and the meaning of !a
for pointer types is "a
is a null pointer" (or strictly speaking "not (value of a
is a non-null pointer)".
However, there's no requirement that a compiler must emit identical code for both, so it's not guaranteed by the C or C++ standard that performance is identical.
By definition, !
requires an operand of type bool
; if its
operand has a type int
, then there is an implicit conversion
(which is nice for obfuscation, but should generally be avoided
otherwise). By definition, the implicit conversion of int a
to bool
is a != 0
. So !a
is !(a != 0)
. In practice,
it's hard to imagine any compiler not generating exactly the
same code for !(a != 0)
as for a == 0
, so performance
certainly shouldn't be a consideration. Say what you mean and
mean what you say: since you are comparing to 0
, that's the
way it should be written.
EDIT:
As Steve Jessop points out, if the type being compared is not
int
, the formal definition of !a
is !(a != static_cast<T>( 0 )
,
where T
is the type of a
. And while implicit conversions
generally hurt readability, I don't think anyone would insist on
an explicit conversion of 0
to another integral type. On the
other hand, I systematically write a == 0.0
for floating point
types, and in C++, a == nullptr
for pointer types—which
involves another implicit conversion, from std::nullptr_t
to
the pointer type. Not all implicit conversions are equal:-).
(FWIW: I'd accept implicit conversions between integral types,
and between floating point types as long as they are not
narrowing, as defined in C++11 §8.5.4/7, except that '\0'
should be used, instead of 0
, for character data; and implicit
conversions between pointers, and between a pointer and an
std::nullptr_t
. Implicit conversions of integral types to
floating point types don't bother me either, although I'd never
write them. But that's about it.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With