【问题标题】:Printing int variables with float format specifier使用浮点格式说明符打印 int 变量
【发布时间】:2013-06-14 08:20:11
【问题描述】:
int main()
{
    int a=5;
    float b=7.5;

    printf("%d %f\n",a,b);
    printf("%d %f\n",a,a);

    return 0;
}

当我在 gcc 编译器中编译时输出是

5 7.500000
5 7.500000

但是在 Visual Studio 中,输出是

5 7.500000
5 0.000000

我无法理解 gcc 编译器的输出。

【问题讨论】:

  • gcc 可能采用给定的最后一个浮点数...
  • 如果转换规范无效,则行为未定义。
  • 为什么visual studio输出结果int a作为浮点数是“0.0000000”?
  • 我猜gcc的输出是因为它在浮点寄存器中将浮点参数传递给printf,而整数在通用寄存器中传递,最后是在那个浮点寄存器中printf("%d %f\n",a,a); 之前是 b
  • @VBB gcc 如何进行最后一次浮动?

标签: c visual-studio gcc floating-point printf


【解决方案1】:

printf原型是:

int printf(const char *format, ...);

C11 (n1570), § 6.5.2.2 函数调用

函数原型声明器中的省略号表示 参数类型转换在最后一个声明的参数之后停止。 默认参数 提升是在尾随参数上执行的。

C11 (n1570), § 6.5.2.2 函数调用

整数提升在每个参数上执行,并且参数 具有 float 类型的提升为 double。这些被称为默认参数 促销活动。

因此,printf 调用不会执行其他参数提升。特别是,a 不会转换为 double。因此它将导致未定义的行为:printf 将尝试获取具有给定大小 (sizeof(double)) 和给定内存表示的 double,这可能与 int 不同。

C11 (n1570), § 7.21.6.1 fprintf 函数

如果转换规范无效,则行为未定义。如果任何参数不是相应转换规范的正确类型,则行为未定义。

此外,您可以查看 gcc 生成的 ASM 代码以了解发生了什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 2011-06-19
    • 1970-01-01
    • 2015-12-31
    相关资源
    最近更新 更多