gcc scanf警告认为浮动是双倍的

时间:2013-09-27 10:57:15

标签: c gcc compiler-warnings scanf

我有一个关于来自gcc编译器的警告消息的问题。当scanf的参数不是指向应该携带用户输入的变量的指针时,会出现警告消息。

#include <stdio.h>

int main(int argc, const char *argv[]) {
    float number;
    scanf("%f", number); /* the value of 'number' is passed, instead of the adress to it */
    return 0;
}

gcc在编译程序时会给出以下警告信息。

scanf-problem.c: In function 'main':
scanf-problem.c:5:5: warning: format '%f' expects argument of type 'float *', but argument 2 has type 'double' [-Wformat=]
     scanf("%f", number);
     ^

与预期的gcc一样,希望scanf的第二个参数具有“float *”类型(指向float的指针)。令我感到困扰的是,gcc认为第二个参数的类型为'double',而实际上它的类型为'float'。

这引出了我的问题,为什么gcc认为scanf的第二个参数是double,当它实际上是一个浮点数时?

我已就此主题进行了一些研究以获得答案,但我找到的每个答案都是关于如何摆脱警告(写'&amp; number'而不是'number')。

5 个答案:

答案 0 :(得分:4)

  

这引出了我的问题,为什么gcc相信第二个论点   当scanf实际上是浮点数时,scanf是double吗?

因为{C}标准

中指定的float被提升为double
  

6.5.2.2函数调用

     

[#6] ......论点          具有float类型的提升为double。这些是          称为默认参数促销。

     

[#7] ...函数原型中的省略号表示法          声明器导致参数类型转换后停止          最后声明的参数。默认参数促销          在尾随参数上执行。

答案 1 :(得分:3)

你已经知道你将错误的东西(如评论中所述)传递给scanf所以只是告诉你警告背后的原因是你提供的float参数首先被提升为double }。

答案 2 :(得分:3)

您的编译器是正确的,传递给scanf的参数确实是double:对于参数列表的...部分,执行一组默认转换。特别是所有float参数都会提升为double,这就是scanf可以看到的内容。

答案 3 :(得分:1)

[编辑]除了发布scanf()原型之外,我现在看到答案回应@chill。
“模仿是最真诚的奉承形式。”


检查原型scanf()

int scanf(const char * restrict format, ...);

...表示允许任意数量的任何类型的参数。由于历史原因,当传递给这些函数时,较小而不是double的所有FP参数都会被提升为double。这就是编译器将其称为double

的原因

charshort也会提升为int

C11 6.5.2.2 6

“...对每个参数执行整数提升,并对其进行参数化 将float类型提升为double。这些被称为默认参数 促销活动。 ......“

答案 4 :(得分:1)

该错误消息具有误导性,scanf期望变量的地址将数据填充回它并且您传递了一个值,并且当scanf查找该地址时发现它与形成“%f”时建议的不同“

您可以将其更改为

scanf("%f", &number); // &number instead of number

它会正常工作