当前位置:  开发笔记 > 编程语言 > 正文

函数声明不是原型

如何解决《函数声明不是原型》经验,为你挑选了3个好方法。

我有一个我创建的库,

mylib.c:

#include 
int
testlib() {
    printf("Hello world\n");
    return (0);
}

mylib.h:

#include 
extern int testlib();

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

myprogram.c:

#include 

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

当我尝试编译该程序时,我收到以下错误:

In file included from myprogram.c:1
mylib.h:2 warning: function declaration isn't a prototype

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

我的问题是,声明函数原型的正确方法是什么?



1> Pramod..:

在C int foo()int foo(void)是不同的功能.int foo()接受任意数量的参数,同时int foo(void)接受0个参数.在C++中,它们的意思相同.我建议你void在没有参数的情况下始终如一地使用.

如果你有一个变量a,extern int a;是一种告诉编译器a可能存在于不同翻译单元中的符号的方法(C编译器代表源文件),在链接时间之前不要解决它.另一方面,作为功能名称的符号无论如何都在链接时被解析.函数(extern,static)上的存储类说明符的含义仅影响其可见性并且extern是默认值,因此extern实际上是不必要的.

我建议删除它extern,它是无关的,通常被省略.


在C*中使用`(void)`*来表示函数不带参数.在C++中,除非您特别需要将代码编译为C和C++,否则只需使用`()`.

2> Keith Thomps..:

快速回答:更改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> angry person..:

尝试:

extern int testlib(void);

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有