Why the use of cin, cout or %I64d is preferred over %lld specifier in C++?

27,521

Solution 1

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.

Solution 2

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.

Share:
27,521
Rishabh
Author by

Rishabh

Updated on January 11, 2022

Comments

  • Rishabh
    Rishabh over 2 years

    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?

  • Rishabh
    Rishabh about 11 years
    I came across this link codeforces.com/blog/entry/417# which says: If you submit under "GNU C++" or "GNU C" option, use this: printf("%I64d\n",n); but NOT this: printf("%lld\n",n); If you submit under "MS C++" option, both variants should work.
  • Mats Petersson
    Mats Petersson about 11 years
    I suspect that's because GNU C is actually using an older MS VC runtime library (since glibc isn't readily available for Windows).