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不进行内部类型转换?
它的用法就是问题所在.除非格式字符串中指定的类型与参数中的类型完全相同,否则事情将无法正常工作.
这是因为编译器将参数按原样推送到堆栈上.
没有类型检查或转换.
在运行时,代码将拉取堆栈的值并根据格式字符串中的值前进到下一个对象.如果格式字符串错误,则高级金额不正确,您将获得有趣的结果.
规则一:您在库或编译器中发现错误的可能性非常非常小.始终假设编译器/库是正确的.
参数通过(变量参数列表)中printf()的机制传递<stdarg.h>,这涉及堆栈上的一些魔术.
没有考虑太多细节,是什么printf()做的是假设,它已经从堆栈拉一个参数是在格式字符串指定的类型-在的情况下%d,一个符号整数.
如果你放在那里的实际值的宽度小于或等于,那么这是有效的int,因为在内部传递给堆栈的任何较小的值都通过int称为" 整数提升 " 的机制扩展到宽度.
然而,这失败了,如果你已经通过的类型printf()是较大的比int:printf()被告知(由你%d),以期待的int,和拉动字节的适当数量(假设4个字节为32位int)从堆栈.
对于你的情况long long,我们假设64位值是8字节,这导致printf()只有你的一半long long.其余的仍然在堆栈中,如果你%d在格式字符串中添加另一个,会产生非常奇怪的结果.
;-)
| 归档时间: |
|
| 查看次数: |
1395 次 |
| 最近记录: |