4

I see the

 #define NUM_MAX_VOLUME 0ui64

in other people's code

What is the number 0ui64? It seems it is not a hex number though.

Nyaruko
  • 4,329
  • 9
  • 54
  • 105

4 Answers4

5

I am surpsised that there are many answers, but none has pointed out the official and authoritative documentation that should be noted in my opinion, so here goes the MSDN documentation:

unsigned-suffix: one of

u U

and

64-bit integer-suffix:

i64 LL ll

So, it is indeed not a hexa number, but basically a macro define to zero that represents an unsiged 64 bit integer number. Please note that 0Ui64, 0ULL, 0ull, etc, would be all the same, too.

This is necessary when you want to make sure that the sign and size are fixed so that it cannot go unexpected or undefined behavior.

This is neither standard C++, nor C, but a Microsoft compiler feature. Try to avoid it.

Since your question is tagged as Qt, the recommendation is to use quint64 and Q_UINT64_C instead which will work cross-platform. So, you would write something like this:

#define NUM_MAX_VOLUME Q_UINT64_C(0)
Community
  • 1
  • 1
László Papp
  • 51,870
  • 39
  • 111
  • 135
3

"ui64" means unsigned 64-bit integer. It is a non-standard suffix in some cases. "0ui64" is just 0, and i guess the reason to write like this is for compatibility.

Lei Chen
  • 699
  • 1
  • 5
  • 13
1

It's basically used in a expression where the size of the operand (the constant here) matters. Take shifting for example:

auto i = 1 << 36;

On a machine where int is 32-bits long this will lead to undefined behaviour. Since the 1 here is taken as an int, and you're trying to shift it beyond the size of the resulting type: int. What you want is a 64-bit integral type, say unsigned long long then you'd do

auto i = 1ULL << 36;

This isn't UB since the resulting type would also be an unsigned long long due to the operand (which is now an unsigned long long too).

Another example is type deduction of the C++11's auto keyword. Try this:

for (auto i = 0; i < v.size(); ++i)

With warnings enabled GCC barks (live example)

warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

However, changing this to

for (auto i = 0u; i < v.size(); ++i)

make the warning disappear. Again since the suffix 0u led the compiler to deduce the type of i as unsigned int and not simply int.

In your case, you've the suffix ui64 which isn't standard C++, so it should be an implementation-specific extension that denotes unsigned 64-bit integer.

Community
  • 1
  • 1
legends2k
  • 31,634
  • 25
  • 118
  • 222
  • `0ULL` makes sense to me, what's the point of bitshifting with `1ULL` though? Why wouldn't you in that context use math.h's `pow(2,36)` – Evan Carroll Mar 05 '18 at 03:05
  • You can use certainly use the `double` variant of `pow`. However, when the base is 2, instead of using the probably less performant `pow`, people use this bit shifting technique. Also this in a situation where you need the power for an `int`. It is a trick based on the fact that powers of two, in binary, have only one 1 digit. – legends2k Mar 05 '18 at 04:11
  • I'm confused, what's less performant? They compile to the same assembly: `unsigned long long = pow(2,16);` – Evan Carroll Mar 05 '18 at 04:13
  • Maybe it's just a style issue and some people find the bit shifting more clear? All good if so? – Evan Carroll Mar 05 '18 at 04:14
  • Well, your compiler's optimizer is doing a good job then; not all compilers may be this smart. However you need to cast the result back to an `int` additionally, no? The other approach avoids these. – legends2k Mar 05 '18 at 04:15
  • @EvanCarroll this is definitely not a style thing; it's an optimization back in the days when compilers weren't this smart. – legends2k Mar 05 '18 at 04:18
  • fair enough `unsigned long long foo = pow(2,4);` just works, generates `mov qword [local_8h], 0x10`. No warning either with `-Wall` using GCC 7.2 – Evan Carroll Mar 05 '18 at 04:19
0

0xFull ,for example, is also valid C++ constant. It is 0xF, unsigned long long, a.k.a. ui64 in Microsoft compilers transcription.

c-smile
  • 26,734
  • 7
  • 59
  • 86
  • Clever, and raised a smile, but it doesn't really answer the question. Probably would have been better as a comment. – paxdiablo Dec 04 '14 at 06:38
  • So basically, it is a very very large number? because 0xF is large. Or, it is system dependent? – Nyaruko Dec 04 '14 at 06:54
  • 0xF = 15 which would normally be an int. The suffix forces the compiler to consider it to be an unsigned long long but the value of it is still 15. – Retired Ninja Dec 04 '14 at 07:12