与LLD,LD和D类标识符为size_t变量的printf [英] printf of a size_t variable with lld, ld and d type identifiers
问题描述
我写了这个小code:
I wrote this tiny code:
#include <stdio.h>
int main() {
size_t temp;
temp = 100;
printf("lld=%lld, ld=%ld, u=%u\n", temp, temp, temp);
return 0;
}
我是 gcc版本4.1.1 20070105(红帽4.1.1-52)上的 i386的GNU / Linux上运行这个机。这是我得到的输出:
I am running this on a i386 GNU/Linux machine with gcc version 4.1.1 20070105 (Red Hat 4.1.1-52). This is the output that I got:
lld=429496729700, ld=100, u=7993461
我可以理解,第一个( LLD
)被打印成垃圾,因为的printf
试图打印8个字节(对于符号long long
作为标志着由 LLD
)的时候只有4个字节可从变量温度
。
但是,我不明白为什么上次标识, U
是越来越打印垃圾 - 而在我的理解这是最接近应用标识符为size_t
。
I can understand that the first (lld
) was printed as garbage because the printf
tries to print 8 bytes (for signed long long
as signified by lld
) when only 4 bytes are available from variable temp
.
But, I fail to understand why the last identifier, u
is getting printed as garbage - whereas, in my understanding this is the closest applicable identifier for size_t
.
在这里,我假设为size_t
是 unsigned int类型
(这是签署了4个字节为我的i386)。
Here I have assumed that size_t
is unsigned int
(which is signed 4 bytes for my i386).
现在,我做了一点调整与的printf
行:
Now, I did a little tweaking with the printf
line:
...
printf("ld=%ld, u=%u, lld=%lld\n", temp, temp, temp);
...
和我有一个完美的罚款答案(除 LLD
部分)。
and I have a perfectly fine answer (except the lld
part).
ld=100, u=100, lld=34331653576851556
有人可以帮我了解我究竟在这里失踪?
Can someone please help me in understanding what exactly am I missing here?
非常感谢您的帮助!
的 [边注:我尝试使用 GCC -O [0,2]
标签上/关闭,而不在观察什么区别切换优化]
[side note: I tried switching optimization using gcc -O[0,2]
tag on/off without any difference in the observation.]
推荐答案
这是因为你已经压入堆栈是3个32位的价值观和格式字符串尝试使用其中四个或者更准确地说,一是64比特值和两个32位值。
That's because what you've pushed on the stack is three 32-bit values and your format string tries to use four of them or, more accurately, one 64-bit value and two 32-bit values.
在第一种情况下,在 LLD
吸收了两个32位的值,在 LD
吸收了第三一个和 U
得到什么恰好是在栈后,这可能真的是任何东西。
In the first case, the lld
sucks up two 32-bit values, the ld
sucks up the third one and the u
gets whatever happens to be on the stack after that, which could really be anything.
当您更改在字符串中的格式说明的顺序,它的工作方式不同,因为 LD
吸收了前32位的值,在 U
吸收了第二和 LLD
吸收了第三的以及的无论发生什么事是之后在栈上。这就是为什么你得到不同的价值观,这是一个数据对齐/可用性问题。
When you change the order of the format specifiers in the string, it works differently because the ld
sucks up the first 32-bit value, the u
sucks up the second and the lld
sucks up the third plus whatever happens to be on the stack after that. That's why you're getting different values, it's a data alignment/availability issue.
您可以与第一个值的动作看到这一点。 429496729700等于(4294967296 + 1)* 100
,即(2 32 +1)* 100。您code段
You can see this in action with the first value. 429496729700 is equal to (4294967296 + 1) * 100
, i.e., (232+1)*100. Your code snippet
printf("lld=%lld, ld=%ld, u=%u\n", temp, temp, temp);
实际上具有以下作用:
actually has the following effect:
What you pass Stack What printf() uses
------------- ----- ------------------
+-----+
100 | 100 | \
+-----+ = 64-bit value for %lld.
100 | 100 | /
+-----+
100 | 100 | 32-bit value for %ld.
+-----+
| ? | 32-bit value for %u (could be anything).
+-----+
在第二种情况下
printf("ld=%ld, u=%u, lld=%lld\n", temp, temp, temp);
将发生以下情况:
the following occurs:
What you pass Stack What printf() uses
------------- ----- ------------------
+-----+
100 | 100 | 32-bit value for %ld.
+-----+
100 | 100 | 32-bit value for %u.
+-----+
100 | 100 | \
+-----+ = 64-bit value for %lld (could be anything).
| ? | /
+-----+
这篇关于与LLD,LD和D类标识符为size_t变量的printf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!