Why many of the Online Judges advises "do not use the %lld specifier to read or write 64-bit integers in С++"
It is preferred to use the cin, cout streams or the %I64d
specifier?
Why many of the Online Judges advises "do not use the %lld specifier to read or write 64-bit integers in С++"
It is preferred to use the cin, cout streams or the %I64d
specifier?
I believe the answer is related to %lld
means long long decimal
, which isn't guaranteed to be 64-bit. It could be, for example 128 bit on some systems. (Although if the variable is long long
rather than, say, uint64_t
, then I expect %lld
is the right thing to use - or it would go wrong the other way around)
Unfortunately, the design of printf
and scanf
and their siblings is such that the compiler implementation and the format must match.
Obviously, cout
and cin
are safe in the sense that the compiler will chose the right output and input translation in itself.
It may also have something to do with what compiler(s) the "online judges" use - I think Microsoft compilers at some point supported 64-bit integers, but not long long
, and thus didn't have %lld
, but did have %l64d
.
The <<
and >>
operators on cin
and cout
have versions for every integer and floating-point type. If you use cin
and cout
, you just do cin >> integer_variable
or cout << integer_variable
and you're done, cin
and cout
will figure out what to do.
If you use some sort of printf()
, then you must be very careful in what you pass to it. If you pass to it an int
, you must also pass its type specifier "%d"
, for unsigned int
it's "%u"
, for long
it's "%ld"
, for unsigned long long
it's "%llu"
, for size_t
it's "%zu"
and so on. If you pass a type specifier that doesn't match the type of your integer, you'll invoke undefined behavior. As a result, your program may print wrong numbers or corrupt itself or hang or crash or misbehave in some other mysterious way.
Now, the C++11 language standard (and C99) has at least one integer type that's 64-bit or longer, long long
(and its unsigned counterpart, unsigned long long
). If you use it, you must be aware that it can be longer than 64 bits. If your compiler provides another type, __int64
or int64_t
(plus the unsigned version of the same), that's exactly 64-bit, you shouldn't mix and match their type specifiers as it's often mistakenly done. You should still use "%lld"
and "%llu"
for long long
and unsigned long long
and whatever's appropriate for __int64
(perhaps, "%I64d"
) and for int64_t
(PRId64
macro).
Basically, you should either avoid using printf()-like
functions or be very careful with them.
Ans to 1:
Because in their background they use compiler. GNU
supports %l64d
, and MS
supports %lld
and %l64d
.
Ans to 2:
Yes, it is preferred to use the cin
, cout
. Because internally they take decision by their own.