我刚刚遇到了一些人的C代码,我很困惑为什么它要编译。有两点我不明白。

与实际函数定义相比,函数原型没有参数。 函数定义中的形参没有类型。


#include <stdio.h>

int func();

int func(param)
{
    return param;
}

int main()
{
    int bla = func(10);    
    printf("%d", bla);
}

为什么会这样? 我已经在几个编译器中测试了它,它工作得很好。


当前回答

这就是为什么我通常建议人们使用以下方法编译代码:

cc -Wmissing-variable-declarations -Wstrict-variable-declarations -Wold-style-definition

这些标志执行了一些事情:

-Wmissing-variable-declarations: It is impossible to declare a non-static function without getting a prototype first. This makes it more likely that a prototype in a header file matches with the actual definition. Alternatively, it enforces that you add the static keyword to functions that don't need to be visible publicly. -Wstrict-variable-declarations: The prototype must properly list the arguments. -Wold-style-definition: The function definition itself must also properly list the arguments.

在许多开源项目中也默认使用这些标志。例如,FreeBSD在Makefile中使用warnings =6构建时启用了这些标志。

其他回答

这就是为什么我通常建议人们使用以下方法编译代码:

cc -Wmissing-variable-declarations -Wstrict-variable-declarations -Wold-style-definition

这些标志执行了一些事情:

-Wmissing-variable-declarations: It is impossible to declare a non-static function without getting a prototype first. This makes it more likely that a prototype in a header file matches with the actual definition. Alternatively, it enforces that you add the static keyword to functions that don't need to be visible publicly. -Wstrict-variable-declarations: The prototype must properly list the arguments. -Wold-style-definition: The function definition itself must also properly list the arguments.

在许多开源项目中也默认使用这些标志。例如,FreeBSD在Makefile中使用warnings =6构建时启用了这些标志。

在C语言中,func()意味着你可以传递任意数量的参数。如果你不想要参数,那么你必须声明为func(void)。传递给函数的类型,如果没有指定,默认为int。

如果函数声明没有形参,即为空,则它将接受不指定数量的参数。如果你想让它不带参数,那么将其更改为:

int func(void);

空参数列表表示“任何参数”,因此定义没有错。 缺失的类型被假定为int型。

我认为任何通过这一点的构建都缺乏配置的警告/错误级别,尽管如此,允许实际代码没有任何意义。

在旧式的声明器中,

标识符列表必须不存在 声明器用于函数定义的头部 (Par.A.10.1)。参数类型信息不为 由声明提供。例如,声明

int f(), *fpi(), (*pfi)();

声明一个函数f返回一个整数,一个函数fpi返回一个整数指针,>和一个指针pfi返回一个整数函数。其中没有指定>的参数类型;它们是老式的。

在new-style声明中

Int strcpy(char *dest, const char *source), rand(void);

Strcpy是 函数返回int,有两个参数,第一个是字符 指针,第二个指针指向常量字符

来源:- K&R书

我希望这消除了你的疑虑。