if we set float and double type to NaN then they are not equal to anything including themselves.
can such a thing happens for int?

- 496,577
- 130
- 894
- 1,212

- 26,084
- 47
- 114
- 191
-
2Not a duplicate of that question at all. This does not ask about NaN. Reopening – Johannes Schaub - litb Oct 16 '10 at 18:54
-
1@Johannes: This is asking if ints have a NaN state, at least how I read it. That's the same as asking if ints can be NaN. – Oct 19 '10 at 08:12
-
2@Roger It ask whether two int variables could compare unequal to themselfs. The questioner gives an example where that happens with float and double. That's about it. As such, it's vastly different. – Johannes Schaub - litb Oct 19 '10 at 19:53
-
1@Roger: 3.9.1/1: "For character types, all bits of the object representation par- ticipate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types." A machine is allowed to have NaN integers, and if it does, `numeric_limits
::has_*_NaN` would be `true` and `…::*_NaN()` would return such a value. (Johannes' answer is much more clever, of course.) – Potatoswatter Oct 19 '10 at 20:07 -
@Johannes: Well, the question only gives us 26 words to go by and no code. Something that short will be interpreted differently. *\*shrug\** – Oct 20 '10 at 03:12
9 Answers
Anything can happen if you compare an uninitialized variable to itself. It is after all undefined behavior. For initialized int variables, this can't happen.
Note that namespace-scope, class-static, and function-static int variables not explicitly initialized are given the value 0. Then they won't compare equal.
I have just tested with Clang:
int main() {
int x;
return (x == x);
}
When compiled with -O1, this returns 0 because the optimizer is allowed to assume that x has no stable value.
GCC is more forgiving with the above, returning 1. The following makes GCC return 0 too (obviously not doing the branch is cheaper if you are allowed to choose):
int main() {
int x;
if(x == x) {
return 1;
}
return 0;
}
In the end, the result is not only dependent on the CPU executing the code, but also from anything else in the toolchain.

- 496,577
- 130
- 894
- 1,212
-
I do believe that your answer is wrong. I think any not-initialized int is equal to itself. We are not talking about any variable. we are talking about primitive "int". – MBZ Oct 16 '10 at 15:30
-
This an _int_ whether it is 'initialized' or not (= containing a random number): how can it ever not equal itself? – slashmais Oct 16 '10 at 15:32
-
Won't the comparation be optimized out by compiler to `true` regrardless of the fact that `a` wasn't initialized? I think that it should have greater precedence (eg you first try to make some generic simplifications, and only after that try to use the complile-time value) – ruslik Oct 16 '10 at 15:33
-
4@slashmais that is entirely up to the implementation. Some processors have special bits that when used in operations produce another special value. Not initialized variables could have such bits set and produce special values when compared to themselfs. ia64's NaT is such an example. – Johannes Schaub - litb Oct 16 '10 at 15:34
-
to Georg: I'm looking from theoritical point of view. actually I can ask the question in one another way: is there any bit representation of int which is not equal to itself in C++? (this happens for floats and doubles) – MBZ Oct 16 '10 at 15:36
-
@Johannes. that's exactly what I'm talking about. The standard says (in 6.2.6.2) that such a bits _exists_ for int, but has no more detail about what it is and how can someone reach it! – MBZ Oct 16 '10 at 15:38
-
@MBZ That's not what you said. You disagreed with me and said "I think any not-initialized int is equal to itself.". – Johannes Schaub - litb Oct 16 '10 at 15:43
-
4@MBZ: Comparing an unitialized int to itself is undefined behavior. They could compare as equal, they could compare as unequal. They could format your hard drive. They could summon Cthulhu. Any use of undefined behavior is, inherently, a bug. Undefined behavior never works - it only *seems* to work. – kyoryu Oct 16 '10 at 15:46
-
I don't believe there exist a **real** processor for which uninitialized integer may be different from itself. After all, 'int' is specifically defined to be the most basic processor operand type – valdo Oct 16 '10 at 16:26
-
@valdo I don't believe it either (not sure how NaTs work). But I don't know, so I won't claim there exist none. All I *do* know is that you are not guaranteed anything when comparing them. – Johannes Schaub - litb Oct 16 '10 at 16:46
-
2It's also the semantics [stated by the LLVM IR](http://llvm.org/docs/LangRef.html#undefvalues): "This example points out that two undef operands are not necessarily the same. This can be surprising to people (and also matches C semantics) where they assume that "X^X" is always zero, even if X is undef.". I think that means, if clang compiles your code, and the LLVM optimizer rushes over it, you should be prepared for `x == x` to yield false. – Johannes Schaub - litb Oct 16 '10 at 16:56
-
6valdo: You are wrong, because you are thinking about processors, and forgetting the compiler. There certainly exist *real* compilers which will optimize code in such a way that a comparison of an uninitialized integer to itself may not always produce the same result as would happen if the comparison returned true. – Brooks Moses Oct 16 '10 at 20:15
Although it's certainly unusual, C++ does allow int
to be NaN
.
First, it's possible for int
to store information besides its numeric value. §3.9.1/1:
For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types.
Then, numeric_limits<int>::has_quiet_NaN
and has_signaling_NaN
are not required to be false
for any type. §18.2.1.2/34-36:
static const bool has_quiet_NaN;
34 True if the type has a representation for a quiet (non-signaling) ‘‘Not a Number.’’
35 Meaningful for all floating point types.
36 Shall be true for all specializations in which is_iec559 != false.
"Meaningful for all floating point types" is a little troublesome as it opens the possibility that the value could be meaningless, but that's certainly an extrapolation.
If numeric_limits<int>::has_quiet_NaN == true
, then numeric_limits<int>::quiet_NaN()
returns such a value.
Obviously, this is not something you should worry about in your code.

- 134,909
- 25
- 265
- 421
-
Come to think of it, subnormal floating-point values could be used as integers, and then you would get "integer" NaN. Their division would need to round towards zero though, which is unusual. – Potatoswatter Feb 05 '15 at 04:49
It cannot happen when you compare plain initialized int variables.
It can happen for int comparisons when you reference a hardware register, e.g. something like:
*timeRegister == *timeRegister
It could also happen when you compare a volatile int variable to itself which is modified by a signal-handler during the comparison.

- 14,786
- 7
- 57
- 75
-
1I guess accessing the same volatile variable twice in the same expression without sequence point in the middle, is also undefined behavior. Right? – Yakov Galka Oct 16 '10 at 15:41
-
This perfectly possible if you compare uninitialized variables.
In C++ language an uninitialized variable is not guaranteed to hold a stable value. In theory operating with uninitialized values produces undefined behavior. In practice reading the value of the same uninitialized variable multiple times can easily result in different values being read. The most obvious practical reason for this is that the variable was optimized to some CPU register.
In order to manage the limited amount of CPU registers efficiently, optimizing compilers operate with the notion of value lifetime of a variable. Value lifetime is essentially the period during which the variable holds a specific stable value. Value lifetime begins when the variable is initialized and ends when it is re-initialized to another value (or when its accessed for the very last time). Within the period of "value lifetime", the value must be stable, so the CPU register cannot be used for other purposes (or it have to be carefully saved and restored every time it is used for other purposes).
Outside the period of value lifetime, there's no need to preserve the value of the register, so it can be freely used for other purposes. For this reason, if some variable is represented by a CPU register, but not initialized (i.e. if its value lifetime hasn't begin yet) its observed value can change absolutely unpredictably, producing the new value every time the variable is read, because the contents of the corresponding CPU register changes for some unrelated reasons.
This might easily result in a == a
evaluating to false
with uninitialized a
. Of course, it is rather surprising to see it happen for two reads that appear to be located so "close" together. But it still can happen. This behavior is prefectly standard. The standard does not guarantee the stability of an initialized variable.

- 312,472
- 42
- 525
- 765
-
Will a non-volatile `a` be actually read 2 times for expression like `a == a` ? I'd expect it to be not read at all. – ruslik Oct 16 '10 at 15:50
-
@ruslik: Who knows? There are many ways to compile the code. In so called "non optimized" code it might be read twice, if the compiler decides to translate it that way. – AnT stands with Russia Oct 16 '10 at 15:52
NaN is the only value for a==a
return false.
And int
doesn't support a NaN value. So no you can't have this situation with int
.
Another note, to check if a value is NaN you should use isnan()
not a==a
.
On the same topic :

- 1
- 1

- 91,525
- 15
- 160
- 151
-
2
-
@Peter, Yes, but I don't think `a==a` is really an elegant check. And most of the time it could be misunderstood by another developer. – Colin Hebert Oct 16 '10 at 15:29
-
1Sometimes `isnan()` spells trouble: http://stackoverflow.com/questions/570669/checking-if-a-double-or-float-is-nan-in-c/2123781#2123781. The direct comparison always works. – Peter G. Oct 16 '10 at 15:33
How about
unsigned int a = -1;
if (a == (unsigned char) a) { //returns false
(...)

- 2,915
- 1
- 20
- 51
Would depend on the compiler optimization maybe; look at the disassembly. If it uses binary 'and' it & check the flags after it will fail if a is zero.

- 7,069
- 9
- 54
- 80
No. The comparation for floats is defines in such way, that NaN compared to any number will return false. Anyway, for ints there is another formula:
ZF = !(a ^ b);
That will give true for any possible value of a.
EDIT: on GCC, with any -O flag, the comparation just dissapears to true.

- 14,714
- 1
- 39
- 40
Since C++20, the answer (for initialized variables) is no.
As proposal P0907 explains, signed integers previously allowed various value representations, including "the existence of an extraordinary value which traps, extra padding bits, [and] integral negative zero." (Hence Potatoswatter's answer that, in theory, NaN values for ints were possible.) In practice, though, every machine running C++ uses a "normal" two's complement representation for signed integers.
Supporting that proposal, the C++ standards committee decided to standardize two's complement and to disallow extraordinary values. Now, the value representation of signed integers is fixed, and while integers can also have padding bits, the standard stops them from doing anything unusual: (basic.fundamental)
Each set of values for any padding bits ([basic.types]) in the object representation are alternative representations of the value specified by the value representation. [Note: Padding bits have unspecified value, but cannot cause traps. In contrast, see ISO C 6.2.6.2. — end note]
Therefore, ints have no extraordinary values that could produce NaN-like behavior.

- 1,625
- 1
- 17
- 29