Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 434
Rishabh Avatar asked Mar 30 '13 11:03

Rishabh


2 Answers

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.

like image 84
Mats Petersson Avatar answered Nov 06 '22 02:11

Mats Petersson


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.

like image 5
Alexey Frunze Avatar answered Nov 06 '22 01:11

Alexey Frunze