【问题标题】:C language - calling functions without function prototypeC语言——调用没有函数原型的函数
【发布时间】:2014-03-16 18:57:10
【问题描述】:

我发现here如果函数在函数调用之下,函数原型在函数调用之前是必需的。

我在 gcc 编译器中检查了这个案例,它编译的代码没有函数原型。

例子:

#include <stdio.h>

//int sum (int, int); -- it runs with this commented line

int main (void)
{
   int total;       
   total = sum (2, 3);
   printf ("Total is %d\n", total);        
   return 0;
}

int sum (int a, int b)
{
   return a + b;
}

能解释一下这个问题吗?

【问题讨论】:

  • 听起来像是 C99 更新
  • 我个人认为避免此类问题的最佳方法是使用“-Wpedantic -ansi”选项编译代码。这样,您的代码甚至无法编译,因为“//”无法识别。 :)

标签: c function-prototypes


【解决方案1】:

如果您在调用之前未提供函数原型,编译器会假定该函数已定义在某个地方,该函数将在链接阶段根据其定义进行链接。默认返回类型假定为int,并且不假定函数参数。这称为隐式声明。这意味着这里假设的函数签名是

int sum();

这里,空参数列表意味着函数sum 采用固定但未知数量的参数,所有这些参数都是未知类型。与函数声明不同

int sum(void);

但是,在C++ 中,上面的两个声明是完全一样的。如果您的函数的返回类型不是int,则假定的函数签名将不匹配,这将导致编译错误。事实上,这是C99C11 的错误。您应该始终在调用之前提供函数原型。

【讨论】:

    【解决方案2】:

    它在this 页面上说:“您不必先声明该函数,但如果您不这样做,C 编译器将假定该函数返回一个 int(即使真正的函数,稍后定义,没有)。”

    已确认here.

    至于论点:“它的论点没有任何假设。”

    【讨论】:

    • 它也接受任意数量的参数。如果我错了,请纠正我。
    • 确实,如果我在上面的代码编译器中将整数更改为双精度值:main.c:22:5: 错误:'sum' main.c:15:17 的类型冲突:注意:先前的隐式'sum' 的声明在这里如果我写 double sum(double, double) 或 double sum() 一切都很好。
    • 函数定义中的参数必须与调用函数的编号相同,并且在执行默认参数提升后,每个参数的类型必须匹配,否则行为未定义。
    【解决方案3】:

    我将您的代码更改为#include

    /* int sum (int, int); -- it runs with this commented line */
    
    int
    main (void)
    {
        int total;
    
        total = sum (2, 3);
        printf ("Total is %d\n", total);
    
        return 0;
    }
    
    int
    sum (int a, int b)
    {
        return a + b;
    }
    

    然后编译:

    gcc --std=c90 -ansi -pedantic node.c
    

    我也尝试了一些standard,但可能与 gcc 版本和 C 标准有关。

    【讨论】:

    • 和?这看起来不像是一个答案。或者我完全没有理解你的意思。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-27
    • 2011-12-30
    • 2011-12-15
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    相关资源
    最近更新 更多