【发布时间】:2018-01-17 09:57:34
【问题描述】:
编辑:实际上这是这个问题的重复 - Why does a function with no parameters (compared to the actual function definition) compile?
我是 C 的初学者,虽然我了解函数原型和默认参数提升机制的需求。我也读了几本 在 SO 上发布有关此主题的帖子。
我仍然对这个简化的 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