【问题标题】:Warning/error "function declaration isn't a prototype"警告/错误“函数声明不是原型”
【发布时间】:2010-09-07 17:07:25
【问题描述】:

我创建了一个库,

文件mylib.c:

#include <mylib.h>

int
testlib() {
    printf("Hello, World!\n");
    return (0);
}

文件mylib.h:

#include <stdio.h>
extern int testlib();

在我的程序中,我尝试调用这个库函数:

文件myprogram.c

#include <mylib.h>

int
main (int argc, char *argv[]) {
    testlib();
    return (0);
}

当我尝试编译这个程序时,我得到以下错误:

在 myprogram.c:1 中包含的文件中
mylib.h:2 警告:函数声明不是原型

我正在使用:gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)

声明函数原型的正确方法是什么?

【问题讨论】:

  • 从 mylib.h 中的声明中删除 extern 特别是如果您正在编写纯 C 程序,则此处不需要 extern 声明。

标签: c gcc


【解决方案1】:

在 C 中,int foo()int foo(void) 是不同的函数。 int foo() 接受任意数量的参数,而 int foo(void) 接受 0 个参数。在 C++ 中,它们的含义相同。我建议您在没有参数的情况下始终使用void

如果你有一个变量aextern int a; 是一种告诉编译器a 是一个可能出现在不同翻译单元中的符号的方法(C 编译器代表源文件),不要解决它直到链接时间。另一方面,作为函数名称的符号无论如何都会在链接时解析。函数上存储类说明符的含义(externstatic)只影响其可见性,extern是默认值,所以extern实际上是不必要的。

我建议删除extern,它是多余的,通常被省略。

【讨论】:

  • 使用(void) in C 表示函数不接受参数。在 C++ 中,除非您特别需要将代码同时编译为 C 和 C++,否则只需使用 ()
  • @Pramod 非常感谢您的解释。天哪,它清理了一切。
【解决方案2】:

快速回答:将int testlib() 更改为int testlib(void) 以指定该函数不接受任何参数。

原型根据定义是一个函数声明,它指定函数参数的类型。

类似的非原型函数声明

int foo();

是一种旧式声明,不指定参数的数量或类型。 (在 1989 年 ANSI C 标准之前,这是该语言中唯一可用的函数声明。)您可以使用任意数量的参数调用这样的函数,并且编译器不需要抱怨——但如果调用与定义不一致,你的程序有未定义的行为。

对于接受一个或多个参数的函数,您可以在声明中指定每个参数的类型:

int bar(int x, double y);

没有参数的函数是一种特殊情况。从逻辑上讲,空括号是指定函数不带参数的好方法,但该语法已用于旧式函数声明,因此 ANSI C 委员会发明了一种使用 void 关键字的新语法:

int foo(void); /* foo takes no arguments */

函数定义(包括函数实际执行的代码)也提供声明。在你的情况下,你有类似的东西:

int testlib()
{
    /* code that implements testlib */
}

这为testlib 提供了一个非原型声明。作为定义,这告诉编译器 testlib 没有参数,但作为声明,它只告诉编译器 testlib 接受一些未指定但固定数量和类型的参数。

如果您将() 更改为(void),则声明将成为原型。

原型的优点是如果你不小心用一个或多个参数调用testlib,编译器会诊断出错误。

(C++ 的规则略有不同。C++ 没有旧式函数声明,空括号特别表示函数不带参数。C++ 支持 (void) 语法以与 C 保持一致。但除非你特别需要您的代码要同时编译为 C 和 C++,您可能应该使用 C++ 中的 () 和 C 中的 (void) 语法。)

【讨论】:

  • “那个参数”附近似乎缺少某些东西
【解决方案3】:

试试:

extern int testlib(void);

【讨论】:

    猜你喜欢
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    相关资源
    最近更新 更多