与LLD,LD和D类标识符为size_t变量的printf [英] printf of a size_t variable with lld, ld and d type identifiers

查看:307
本文介绍了与LLD,LD和D类标识符为size_t变量的printf的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了这个小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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆