gpt4 book ai didi

c - 在 printf 参数中提升类型是否危险?

转载 作者:太空狗 更新时间:2023-10-29 17:10:43 25 4
gpt4 key购买 nike

我的问题源于在尝试为多个位深度平台(例如 32/64)构建时尝试使用 printf 记录内容。

一个不断抬头的问题是试图在多种架构上打印整数。在 32 位上它会是这样的

printf(" my int: %d\n", myInt);

但在 64 位上,它必须更改为

print (" my int: %ld\n", (long)myInt);

我有两个相关的问题:

  1. 我的第一个想法是,当您告诉 printf 打印一个变量并为其指定格式时,它会查看该变量的地址并获取该格式所需的字节数。起初这似乎是个大问题。例如,如果您有一个变量 myChar,它是一个 char(1 个字节),但使用了 %d 的格式说明符,这将告诉 printf 转到 myChar 的地址并获取接下来的 4 个字节,将其视为一个 int。如果是这种情况,似乎 printf 会从相邻变量中获取垃圾日期(因为它正在获取 4 个字节,但实际值只有 1 个字节)。然而,情况似乎并非如此。通过使用 myChar 并指定 %d,printf 获取 1 个字节,然后用 0 填充高 3 个字节。我的理解对吗?

  2. 如果上述情况属实,那么始终将变量提升到最大值以避免 32/64 位情况下出现的问题类型是否真的有害。例如,如果您有一个 short 变量 myShort 和一个 int 变量 myInt,将它们始终打印为是否有任何缺点:

    printf("myShort %ld", (long)myShort);printf("myInt %ld", (long)myInt);

感谢任何澄清。

最佳答案

关于 printf:在您选择的情况下,“%d”必须根据规范处理平台定义的“int”数据类型。它是 32 位、64 位还是 128 位线性 AS/400 值并不重要。如果您想将该值提升为更大的字段类型(并将该提升与相关格式字符串粒子匹配),您当然可以这样做,

int a=0;
printf("%ld", (long)a);

肯定是使用促销定义的行为。

我觉得你问题的真正症结在于下面这样的情况,强制推广是否能“解决”出现的任何问题。例如:

char ch = 'a';
printf("%d", ch);

或者关于:

char ch = 'a';
printf("%ld", (long)ch);

或者可能是这样(这是您似乎试图避免的真实情况):

char ch = 'a';
printf("%ld", ch);

其中第一个会起作用,但这只是因为在 va-arg 列表上堆栈推送的任何内容的最小大小是 int 的平台大小。编译器会为您自动将值提升为 int。由于“%d”需要一个平台int,所以一切都会很好。

第二个总是并且得到完全支持。从 charlong 有明确定义的提升。即使 long 是 64 位(或更大)它仍然可以工作。

第三个是一路UB。 printf 正在寻找一个 long 并且将只显示一个 int 的字节。如果这似乎在您的平台上“有效”,那么请检查您的平台宽度的 intlong。它可能“有效”只是因为您的平台 longint 位宽相同。将代码移植到它们不在的平台时,它会带来有趣的惊喜,并且由于它是通过 va-arg 推送的,所以直到真正不同的宽度开始播放时,您才会看到它。

综上所述,现在将实际的 地址 扔给某些东西(任何东西,真的),例如 scanf 所需的东西,我们正在寻找完全不同的东西.

int val;
sscanf("%ld",&val);

这是一个等待发生的段错误。就像上面一样,您永远不会知道您的平台 long 和平台 int 的宽度是否相同。将此代码放入 longint 大小不同的框中,并为随后的核心文件的 gdb 加载做好准备。

关于c - 在 printf 参数中提升类型是否危险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12995789/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com