【问题标题】:MSVC++ handling unsigned long long intMSVC++ 处理 unsigned long long int
【发布时间】:2011-03-24 03:50:56
【问题描述】:

我对 MSVC 处理无符号长长整数的方式有疑问。这是要重现的代码:

// test.cpp (note extension)
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    unsigned long long int address = 0x0A0B0C0D0E0F;
    printf("Address=%llu\n", address);

    printf("%02X:%02X:%02X:%02X:%02X:%02X\n",
            ((address >> (5 * 8)) & 0xff),
            ((address >> (4 * 8)) & 0xff),
            ((address >> (3 * 8)) & 0xff),
            ((address >> (2 * 8)) & 0xff),
            ((address >> (1 * 8)) & 0xff),
            (address & 0xff));

    printf("%02X:", ((address >> (5 * 8)) & 0xff));
    printf("%02X:", ((address >> (4 * 8)) & 0xff));
    printf("%02X:", ((address >> (3 * 8)) & 0xff));
    printf("%02X:", ((address >> (2 * 8)) & 0xff));
    printf("%02X:", ((address >> (1 * 8)) & 0xff));
    printf("%02X\n", (address & 0xff));

    exit(0);
}

当我在 linux 上编译它时,我得到(如预期的那样):

Address=11042563100175
0A:0B:0C:0D:0E:0F
0A:0B:0C:0D:0E:0F

但是,当我在 MSVC++ 2008 Express 上编译它时,我得到:

Address=11042563100175
0A:00:0B:00:0C:00
0A:0B:0C:0D:0E:0F

我的 printf 语句格式是否错误?或者 MSVC 在移位/和操作之后是否在堆栈上留下一个额外的字节?还是有其他问题?

注意:使用 MSVC 编译时,您需要使用“.cpp”文件扩展名来强制使用 C++ 模式。我相信这是因为直接 C 模式下的 MSVC 不包括(全部)C99,其中包括 printf 的 '%llu' 标志。

西蒙。

【问题讨论】:

  • 嗯。似乎 MSVC 在 printf 中的堆栈处理确实是问题所在。在这种情况下,它只从堆栈中弹出一个 long,剩下的 long 的另一半。转换为 int 似乎可以解决问题。
  • 这不是问题,这是正确的行为。 printf 是一个可变参数函数,你作为程序员负责类型安全。 %X 格式说明符承诺一个int,通过传递一个unsigned long long,所有的赌注都被取消了。

标签: c++ visual-c++


【解决方案1】:

%X 格式说明符需要一个 32 位参数。你正在传递 64 位,扔掉堆栈。您可以使用 %llX。 CRT 与 C 和 C++ 代码相同。

【讨论】:

    猜你喜欢
    • 2016-07-29
    • 1970-01-01
    • 2012-01-27
    • 2016-12-20
    • 2013-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多