【问题标题】:C prototype functions and default argument promotions in C function calls [duplicate]C函数调用中的C原型函数和默认参数提升[重复]
【发布时间】:2018-01-17 09:57:34
【问题描述】:

编辑:实际上这是这个问题的重复 - Why does a function with no parameters (compared to the actual function definition) compile?

我是 C 的初学者,虽然我了解函数原型和默认参数提升机制的需求。我也读了几本 在 SO 上发布有关此主题的帖子。

  1. Default argument promotions in C function calls
  2. C prototype functions

我仍然对这个简化的 sn-p 获得的警告和最终结果感到困惑。

#include <stdio.h>

void impl();

int main(void)
{   
    impl(3.0);
    return 0;
}

void impl(val)
{
    printf("%.2f", val);
}

我收到以下警告:format specifies type 'double' but the argument has type 'int' [-Wformat] 对于这一行 printf("%.2f", val);

我不明白为什么编译器认为val 应该被视为int 而不是执行默认参数提升。我还读到,如果您不提供参数类型:

ANSI C 编译器会假定您已决定放弃函数原型,并且它不会检查参数。

打印到控制台的结果是 0.00,但据我了解,调用者会将双精度放在堆栈上,%f 也意味着 printf 中的双精度,所以它读取双精度出栈,结果不应该受到影响。虽然这个问题C Function with parameter without type indicator still works? 解释了一些问题,但我仍然不明白这个问题到底。我也找不到在哪里声明没有类型的参数应该被编译器视为类型int

我觉得这部分我没看懂6.5.2.2“函数调用”标准里写的:

如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,而浮点类型的参数提升为双精度。这些称为默认参数提升。

在 Windows 10 下使用 clang 6.0--std=c89 标志编译。

【问题讨论】:

  • 您已经声明了impl(),但它没有原型。您使用隐式 int 参数定义它。这在 C90 中是允许的(为了向后兼容),但在 c99 中被禁止。其他问题是这些问题的后果。
  • @JonathanLeffler 是的,我知道我定义了一个带有隐式参数的函数,但我找不到声明隐式参数被视为类型int 的来源。能给我链接吗?
  • 这在 C89 标准中的第 3.7.1 节“语义”部分下进行了说明。

标签: c prototype function-prototypes promotions


【解决方案1】:

这个:

void impl(val)

没有指定val 参数的正式类型。这使其默认为int。这与在运行时传递给函数的值类型无关,如果函数从未被调用过,情况同样如此。

我认为,省略类型也很老派,在现代 C 中不受支持。

【讨论】:

    猜你喜欢
    • 2010-11-18
    • 2020-09-02
    • 1970-01-01
    • 2012-08-23
    • 2014-02-10
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多