gpt4 book ai didi

c - 当 x 是有符号字符时,为什么 mingw 对 printf ("%d",x) 发出警告?

转载 作者:行者123 更新时间:2023-11-30 18:13:21 27 4
gpt4 key购买 nike

当我编译时

signed char x=1;
printf("%d",x);

使用 mingw,我收到以下警告:

format '%d' expects argument of type 'int *', but argument 2 has type 'signed char *' [-Wformat=]

我知道 %d 打印十进制整数而不是字符,而且我还传递一个(有符号)char 指针作为第二个参数。但是 x 不应该提升为 int 然后正确打印吗?

为什么 mingw 在这里警告我?

编辑:抱歉,这个警告实际上是由 scanf 调用产生的:

signed char x;
scanf("%d",&x);

(其他代码在没有警告的情况下编译。)

我认为这是因为 scanf 会尝试写入 int 的字节数,而我只为 char 保留存储,这可能会产生运行时错误...?

最佳答案

参数的类型必须与相应的转换说明符匹配,否则行为未定义,这意味着编译器不必以任何特定方式处理这种情况;事实上,您甚至收到警告是因为编译器编写者超出了标准的要求(并且因为这是一个常见错误)。

问题是 %d指定相应的参数指向 int 类型的对象,它很可能比 char 类型的对象大。您的scanf调用假设它有 sizeof (int)要写入的字节,但要写入的对象只有 1 个字节宽(定义为 sizeof (char) == 1)。一种可能的后果是写入了错误的字节,从而导致充其量意外的输入。

例如,假设 sizeof (int) == 4、x的地址是 0x4000 ,并且这是一个big-endian架构,这意味着多字节类型中的最高有效字节存储在指定的地址处。这就是声明和初始化 x 后内存的样子。 :

         +----+
0x4000: | 01 | <-- x
+----+
0x4001: | ?? |
+----+
0x4002: | ?? |
+----+
0x4003: | ?? |
+----+

哪里??表示未知的字节值。现在,假设在 scanf打电话,你输入2 。因为转换说明符是 %dscanf调用将假设它正在写入 int对象,这意味着你的内存将如下所示:

         +----+
0x4000: | 00 | <-- x
+----+
0x4001: | 00 |
+----+
0x4002: | 00 |
+----+
0x4003: | 02 |
+----+

当您检查x时,它将包含 0 ,这不是您所期望的。此外,x之外的内存已被修改,这可能会导致其他问题。

同样,这是基于特定架构细节的一种可能的结果;在小端架构上,它似乎可以工作,因为最低有效字节位于 0x4000 ,但您仍然在该对象的边界之外写入。

编辑

正如 DevSolar 指出的,您应该使用 %hhd转换说明符,如果您打算读取数值并将其存储到 char对象(即,您想要存储 2 而不是 字符 '2' )。如果要存储单个字符值( '2''a''?' 等),请使用 %c转换说明符。

关于c - 当 x 是有符号字符时,为什么 mingw 对 printf ("%d",x) 发出警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26143158/

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