简体   繁体   中英

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't understand why this printf behaves like that? Neither init or pageSize is 0. I understand that %d is not valid for unsigned long long, but what bothers me is that printf's behavior changes when argument's order change.

Neither init or pageSize is 0.

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

More than likely, you'll need to use %ld (if your longs are 64 bit) or %lld (if your long longs are 64 bit) or the fixed-width specifier macros from the latest C standard that I can never remember off the top of my head, assuming they're available in your environment :-)

That whole problem would probably disappear if you embraced C++ rather than that half-ground which many coders seem to exist in (using legacy stuff like stdio.h when better alternatives are available). You should use the type-aware:

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

It also helps to have a compiler that's a bit intelligent, and ensure you use that 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 truly interested in the mechanics as to why the values change based on their order in the printf , see this answer .

It goes into detail about what things (and more importantly, the sizes of those things) get pushed on the stack, comparing them with what you told printf would be there.

Long story writ short: you lied to printf so it treated you the same way your significant other would, had you been caught lying to them :-)

First printf in fact prints the LO and HI DWORDs of the DWORD64 variable last (which is 4095, i believe). Second printf prints the LO and HI DWORDs of the DWORD64 variable first (which is 0). The second DWORD64 parameter is ignored in both lines...

My guess is in the environment you're targetting %d is not for 64-bit quantities. Try %I64 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM