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

3

24

Why do many of the online judges advise "do not use the %lld specifier to read or write 64-bit integers in С++"?

Is it preferred to use the cin, cout streams or the %I64d specifier?

Acidulent answered 30/3, 2013 at 11:30 Comment(5)
Because you can't be sure long long is 64 bit long, for example?Indigestible
Because using printf is not type safe. If user passes some other type then it gives you Undefined behavior. While with cout the compiler appropriately chooses an valid overload version depending on the type or it returns an error, there is no Undefined behavior.Mineral
@AlokSave but why %I64d has been preferred over %lld ?Acidulent
https://mcmap.net/q/583558/-problem-with-lld-on-windowsRollmop
The first comment under the Q answers that for you.My comment answers the second Q. To be more specific on the first comment. %l64d is the format specification which tells the compiler that the number passed as argument will be 64 bit long. But it is not necessary that the type long long used to store these numbers are actually 64 bit on every environment. Any mis-match in format specification and actual data being passed to printf technically gives you an Undefined behavior. So this type unsafe behavior might bite you badly.Mineral
H
17

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.

Hardener answered 30/3, 2013 at 11:43 Comment(2)
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.Acidulent
I suspect that's because GNU C is actually using an older MS VC runtime library (since glibc isn't readily available for Windows).Hardener
T
6

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.

Telephony answered 30/3, 2013 at 11:58 Comment(0)
C
-1

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.

Corpuz answered 11/1, 2022 at 3:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.