int64_t method_one = 0;
...is perfectly reasonable. C99 (see e.g. draft here; yes, I know it's not the most recent standard any more, but it's the one that introduced the int<N>_t
types) says that:
- the
0
has type int
(§6.4.4.1 para.5);
- the type of the expression is
int64_t
(§6.5.16 para.3);
- the type of the right-hand side will be converted to the type of the expression (§6.5.16.1 para.2);
- this conversion will not change the value (§6.3.1.3 para.1).
So there's nothing wrong with that at all, and the lack of additional clutter makes it the most readable of the options when initialising to 0 or anything else in the range of an int
.
int64_t method_two = 0LL;
int64_t
is not guaranteed to be the same as long long
; however, this should in fact work portably for any signed 64-bit value as well (and similarly ULL
for unsigned 64-bit values): long long
(and unsigned long long
) should be at least 64 bits in a C99-compliant implementation (§5.2.4.2.1), so LL
(and ULL
) should always be safe for initialising 64-bit values.
int64_t method_three = INT64_C(0);
This is arguably a better option for values which may be outside the range of an int
, as it expresses the intent more clearly: INT64_C(n)
will expand to something appropriate for any n
in (at least) a 64-bit range (see §7.18 in general, and particularly §7.8.4.1).
In practice, I might well use any of the above, depending on context. For example:
uint64_t counter = 0;
(Why add unnecessary clutter?)
uint64_t some_bit = 1ULL << 40;
(1 << 40
simply won't work unless int
is unusually wide; and UINT64_C(1) << 40
seems less readable to me here.)
uint64_t some_mask = UINT64_C(0xFF00FF00FF00FF00);
(In this case, explicitly calling out the value as a 64-bit constant seems more readable to me than writing 0xFF00FF00FF00FF00ULL
.)