I'm guessing you're writing (uint64_t)-1 instead of -1ULL because you don't want to make assumptions about the size of unsigned long long? If so, that's good. However, there is an alternative which hasn't been mentioned yet (and doesn't actually answer your question) but can save a lot of worry by side-stepping the question:
An alternative
A good habit to be in is to always use UINT64_C(x) instead of (uint64_t)x. This is a macro defined in <stdint.h> which automatically appends U, UL, or ULL as needed. Thus, UINT64_C(-1) resolves to either -1U, -1UL, or -1ULL, depending on your target. This is guaranteed to always work correctly.
Perils of type-casting
Note that (uint64_t)x actually does not even work correctly in general. For example,
(uint64_t)2147483648 // RISKY
generates a warning on some compilers because the value 2147483648 (2^31) is too big to fit into a 32-bit integer, and the following does not even remotely work:
(uint64_t)1000000000000000000 // RISKY
However, if you use UINT64_C() instead, then everything is golden:
UINT64_C(2147483648) // GOOD
UINT64_C(1000000000000000000) // GOOD
UINT64_C(-1) // GOOD
Notes:
- The
_C suffix stands for “constant.”
- In
<stdint.h> there are also 8-, 16-, and 32-bit versions for both signed and unsigned values.
- For the special case of –1, you could also just write
UINT64_MAX.