简体   繁体   English

奇怪的printf行为

[英]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? 我不明白为什么这个printf表现得那样? 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. init或pageSize都不是0.我理解%d对无符号long long无效,但令我困扰的是当参数的顺序改变时printf的行为会发生变化。

Neither init or pageSize is 0. init或pageSize都不是0。

Nor is %d a suitable format string specifier for a 64-bit value, I'd bet :-) 对于64位值, %d也不是合适的格式字符串说明符,我敢打赌:-)

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 :-) 更有可能的是,你需要使用%ld (如果你的long是64位)或%lld (如果你的long长度为64位)或者来自最新C标准的固定宽度说明符宏,我永远不会记得假设它们在您的环境中可用,我的头脑:-)

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). 如果你接受C ++而不是许多程序员似乎存在的那种半边界(使用像stdio.h这样的传统东西,当有更好的替代品可用时),整个问题可能会消失。 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 . 对于那些真正对机制有兴趣的人,为什么值会根据他们在printf的顺序而变化,请参阅这个答案

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. 它详细介绍了什么东西(更重要的是,这些东西的大小)被推到了堆栈上,将它们与你告诉printf内容进行比较。

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 :-) 长话短说:你骗了printf所以它对待你就像你的另一个人一样,如果你被抓到骗他们:-)

First printf in fact prints the LO and HI DWORDs of the DWORD64 variable last (which is 4095, i believe). 事实上,第一个printf last打印了DWORD64变量的LO和HI DWORD(我相信这是4095)。 Second printf prints the LO and HI DWORDs of the DWORD64 variable first (which is 0). 第二个printf打印出DWORD64变量的LO和HI个DWORD first (其为0)。 The second DWORD64 parameter is ignored in both lines... 两行中都忽略第二个DWORD64参数...

My guess is in the environment you're targetting %d is not for 64-bit quantities. 我的猜测是在你所针对的环境中%d不适用于64位数量。 Try %I64 . 试试%I64

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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