来自printf的长long int的结果不一致?

Sun*_*hah 1 c c++ printf

struct DummyStruct{
        unsigned long long std;
        int type;
};

DummyStruct d;
d.std = 100;
d.type = 10;

/// buggy printf, unsigned long long to int conversion is buggy.
printf("%d,%d\n",d.std, d.type);  // OUTPUT: 0,100 
printf("%d,%d\n", d.type, d.std); // OUTPUT: 10,100 
printf("%lld,%d\n",d.std, d.type); // OUTPUT: 100,10
Run Code Online (Sandbox Code Playgroud)

请告诉我为什么在printf中没有正确处理unsigned long long to int转换.我正在使用glibc.

这是printf中的错误吗?

为什么printf不进行内部类型转换?

xto*_*ofl 13

%d参数告诉printf解释相应的参数作为int.尝试使用%llulong long.并记住这张参考卡.

(所以不,这不是一个bug)

  • (这是一个错误,但不是'printf`而是上面的程序:-)) (8认同)

Mar*_*ork 5

它的用法就是问题所在.除非格式字符串中指定的类型与参数中的类型完全相同,否则事情将无法正常工作.

这是因为编译器将参数按原样推送到堆栈上.
没有类型检查或转换.

在运行时,代码将拉取堆栈的值并根据格式字符串中的值前进到下一个对象.如果格式字符串错误,则高级金额不正确,您将获得有趣的结果.


Dev*_*lar 5

规则一:您在库或编译器中发现错误的可能性非常非常小.始终假设编译器/库是正确的.

参数通过(变量参数列表)中printf()的机制传递<stdarg.h>,这涉及堆栈上的一些魔术.

没有考虑太多细节,是什么printf()做的是假设,它已经从堆栈拉一个参数是在格式字符串指定的类型-在的情况下%d,一个符号整数.

如果你放在那里的实际值的宽度小于或等于,那么这是有效的int,因为在内部传递给堆栈的任何较小的值都通过int称为" 整数提升 " 的机制扩展到宽度.

然而,这失败了,如果你已经通过的类型printf()较大的int:printf()被告知(由你%d),以期待的int,和拉动字节的适当数量(假设4个字节为32位int)从堆栈.

对于你的情况long long,我们假设64位值是8字节,这导致printf()只有你的一半long long.其余的仍然在堆栈中,如果你%d在格式字符串中添加另一个,会产生非常奇怪的结果.

;-)