I understand 0u
means 0 unsigned, but what does the ~
at the beginning mean? Does it signify inversion in this case or does it mean something else?

- 30,738
- 21
- 105
- 131

- 873
- 1
- 10
- 24
-
25And this is why `numeric_limits
::max()` is a thing. – Billy ONeal Oct 24 '14 at 19:46 -
6Be careful because if you store the result in a larger integer, the extra bits are still 0. – Neil Kirk Oct 24 '14 at 19:53
4 Answers
It indicates bitwise not; all bits in the integer will be flipped, which in this case produces a number where all bits are 1.
Note that since it is unsigned, if the integer is widened during assignment the extended bits would be 0. For example assuming that unsigned short
is 2 bytes and unsigned int
is 4:
unsigned short s = ~0u; // 0xFFFF
unsigned int i = s; // 0x0000FFFF
If you need to invert the bits of some generic numeric type T
then you can use the construct ~(T(0))
.

- 158,093
- 24
- 286
- 300
-
3Very sneaky, I've never seen that before. I think that falls into the column of obscure-but-it-works-i-guess. – Cory Kramer Oct 24 '14 at 19:54
-
7
-
I get how it works, but if it takes a minute to look at to figure out what it is supposed to be doing, it lacks readability IMHO – Cory Kramer Oct 24 '14 at 22:05
-
6@Cyber I disagree; I'd expect professional C++ developers to *at least* know what operators exist in the language and what they do. If it bothers you, then you can write `template
T bitwise_not(T v) { return ~v; }`, but be prepared for mocking if you do that in a professional setting. ;) – cdhowie Oct 24 '14 at 22:21 -
1Implying I'm not already a professional C++ developer :) It's what I do for a living – Cory Kramer Oct 24 '14 at 22:37
-
I'm implying that a professional C++ developer *should* know all of the operators in the language. We're not talking template metaprogramming here, we're talking the basic stuff that any decent tutorial would cover. I'm not intending this as an insult, only as a defense of my statement that this is not exactly an "obscure" language feature. – cdhowie Oct 24 '14 at 22:48
-
2Point taken, I just would prefer something like `numeric_limits
::max()` as that is very clear at first glance what you are shooting for. – Cory Kramer Oct 24 '14 at 22:50 -
7@Cyber Depending on the context. If the goal is "largest integer of this type" then yes, I absolutely 100% agree that would be better. If the goal of the assignment is to create a bitfield with all bits on, `~0` is clearer and more appropriate in that context. – cdhowie Oct 24 '14 at 22:52
-
4This kind of thing is very common in C programming, and in code that deals with C-level stuff (systems programming, hardware interfaces) or even just stuff like status flags, bitfields, etc. you will see this type of code (`~0`) a lot. – nneonneo Oct 25 '14 at 02:05
It means a bitwise not which flips all the bits of the integer value by giving you a number with all bits set to 1.
(Assuming a 32 bit uint)
0u
00000000 00000000 00000000 00000000
~0u
11111111 11111111 11111111 11111111
3
00000000 00000000 00000000 00000011
~3
11111111 11111111 11111111 11111100
If the machine uses a 2's complement representation for negative integers, then casting ~0u
to a signed integer is equivalent to -1
. More on this in Stack Overflow question Is there a difference between -1 and ~0?.
-
1-1: `~0u` never means -1 -- it is unsigned! (Casting it to a signed integer may though) – Billy ONeal Oct 24 '14 at 19:58
-
1
-
1
-
-
@BillyONeal Seems a bit nitpicky to me. Since the standard guarantees 2's complement behavior for unsigned, then it also guarantees that it is an additive Abelian group. Thus `~0u` is always guaranteed to be equivalent to `-1` in the sense that `~0u + 1u == 0u` (i.e. `~0u` is the additive inverse of `1u`). Also: http://stackoverflow.com/questions/22801069/using-1-as-a-flag-value-for-unsigned-size-t-types/22801135#22801135 – Tim Seguine Oct 25 '14 at 17:23
-
@TimSeguine the standard guarantees *wraparound* behavior for unsigned overflow. It never guarantees 2's complement; 2's complement is a way of encoding sign and unsigned integers have no sign. If a value cannot be represented by the destination type (which is the case for UINT_MAX -> signed int) then the behavior is implementation defined. On 2's complement machines that typically means -1; but throwing an interrupt or setting any other value would be conforming behavior. On signed magnitude machines the result is likely INT_MIN, and that's also valid. – Billy ONeal Oct 25 '14 at 17:44
-
@TimSeguine the answer you linked to is about converting signed to unsigned, not vice versa. Whole different animal because signed overflow is undefined behavior while unsigned overflow is not, – Billy ONeal Oct 25 '14 at 17:46
-
@BillyONeal The guaranteed wraparound behavior plus the required behavior in the answer I linked to, mean that it essentially must behave like 2's complement on any conforming implementation, in a very defined sense. Every valid value of unsigned has an additive inverse, and it happens to be the 2's complement of that number on any conforming implementation. – Tim Seguine Oct 25 '14 at 17:54
-
@TimSeguine nope. Going -1 to unsigned wraps around 0 to UINT_MAX, because going from signed to unsigned has defined overflow behavior. The reverse transform has implementation defined behavior. See C++11 4.7 [conv.integral]/3 – Billy ONeal Oct 25 '14 at 17:59
This operator is better described in the C Standard than in the C++ Standard
4 The result of the ~ operator is the bitwise complement of its (promoted) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set). The integer promotions are performed on the operand, and the result has the promoted type. If the promoted type is an unsigned type, the expression ~E is equivalent to the maximum value representable in that type minus E.
Thus ~0u
means the maximum value of an object of type unsigned int when each bit of its internal representation is set to 1.
Consider using the operator that to set for example the first n bits to 1. The expression will look like
~( ~0u << n )
If you want to set n bits starting from m position then you can write
~( ~0u << n ) << m

- 301,070
- 26
- 186
- 335
It is to invert the values in bits. For example:
00000000000000000001
to
11111111111111111110
This is what ~
does.

- 30,738
- 21
- 105
- 131

- 49
- 1