Strange printf behavior

std::vector<DWORD64> v; for(size_t i = init; i < pageSize; ++i) v.push_back(i); DWORD64 last = *(v.rbegin()); DWORD64 first = *(v.begin()); printf("%d %d \n", last, first); printf("%d %d \n", first, last); 

outputs:

 4095 0 0 0 

I can not understand why this printf behaves like this? Neither init nor pageSize are equal to 0. I understand that% d is not valid for unsigned long long, but what worries me is that printf behavior changes when the order of the arguments changes.

+4
source share
3 answers

Neither init nor pageSize is 0.

Nor is %d suitable format string specifier for a 64-bit value, I would put :-)

Most likely you will need to use %ld (if your long bits are 64 bits) or %lld (if your long long bits are 64 bits) or fixed-width specifier macros from the latest C standard, which I cannot remember head to head assuming they are available in your environment :-)

This whole problem is likely to disappear if you turn on C ++, and not the half on which many coders seem to exist (using outdated things like stdio.h when better alternatives are available). You should use type:

 std::cout << a << ' ' << b << '\n'; 

It also helps to have a compiler that is a bit intelligent, and make sure you use this intelligence:

 pax$ cat qq.cpp #include <iostream> #include <vector> #include <cstdio> int main (void) { std::vector<int> v; v.push_back (111142); v.push_back (314159); long long a = *(v.begin()); long long b = *(v.rbegin()); printf ("%6d %6d, a then b, bad\n", a, b); printf ("%6d %6d, b then a, bad\n", b, a); std::cout << a << ' ' << b << ", good\n"; return 0; } pax$ g++ -Wall -Wextra -o qq qq.cpp qq.cpp: In function 'int main()': qq.cpp:11: warning: format '%d' expects type 'int', but argument 2 has type 'long long int' qq.cpp:11: warning: format '%d' expects type 'int', but argument 3 has type 'long long int' : : : : : qq.cpp:12: warning: format '%d' expects type 'int', but argument 3 has type 'long long int' pax$ ./qq 111142 0, a then b, bad 314159 0, b then a, bad 111142 314159, good 

For those who are really interested in mechanics as to why the values ​​of the values ​​change depending on their order in printf , see this answer .

It goes into detail about what things (and more importantly, the sizes of these things) get on the stack, comparing them to what you told printf .

In short, you lied to printf to treat you like your significant other if you were caught lying to them :-)

+10
source

The first printf actually prints the LO and HI DWORDs of the DWORD64 last variable (this is probably 4095). The second printf prints the LO and HI DWORDs of the DWORD64 first variable (which is 0). The second DWORD64 parameter is ignored on both lines ...

+1
source

My hunch in the environment that you are aiming at %d is not for 64-bit values. Try %I64 .

0
source

Source: https://habr.com/ru/post/1398187/


All Articles