首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >带参数但没有类型指示符的C函数仍然有效吗?

带参数但没有类型指示符的C函数仍然有效吗?
EN

Stack Overflow用户
提问于 2013-08-13 14:37:28
回答 6查看 6.4K关注 0票数 21

代码如下:

代码语言:javascript
复制
int func(param111)
{
    printf("%d\n", param111);
    return param111;
}

int main()
{
    int bla0 = func(99);
    int bla1 = func(10,99);
    int bla2 = func(11111110,99,10001);
    printf("%d, %d, %d\n", bla0, bla1, bla2);
}

编译结果:

代码语言:javascript
复制
zbie@ubuntu:~$ gcc -Wall -g -std=c99 -O2 zeroparam.c

zeroparam.c: In function ‘func’:

zeroparam.c:2: warning: type of ‘param111’ defaults to ‘int’

运行结果:

代码语言:javascript
复制
zbie@ubuntu:~$ ./a.out

99

10

11111110

99, 10, 11111110

我知道如果函数没有参数,代码应该没问题,比如int func(),它可以接受任何输入。但是,如何成功编译和运行这些代码呢?

EN

回答 6

Stack Overflow用户

发布于 2013-08-13 14:38:53

此行为是为了向后兼容旧版本的语言,即语言的K&R版本。当GCC遇到“旧风格”函数时,它符合旧的K&R C行为,在这种情况下没有任何警告。

实际上,如果您将函数更改为:int func(int param111),您将获得预期的警告:do

代码语言:javascript
复制
x.c: In function ‘main’:
x.c:11:5: error: too many arguments to function ‘func’
x.c:2:5: note: declared here
x.c:12:5: error: too many arguments to function ‘func’
x.c:2:5: note: declared here
x.c:14:1: warning: control reaches end of non-void function [-Wreturn-type]

(使用GCC 4.7.3和"gcc -std=c99 -Wall x.c && ./a.out“测试)

或者引用评论中的JeremyP:“在K&R中,调用一个带有任意多个参数的函数是非常好的,因为省略符号还没有发明出来。”

请注意,编译器可以显示任意数量的额外警告,但仍然符合标准。例如,Apple的编译器会对此代码发出警告。

票数 20
EN

Stack Overflow用户

发布于 2013-08-13 14:50:57

函数声明被解释为K&R样式的函数声明,因为它缺少类型。在标准中,这被称为带有标识符列表的函数声明,而不是通常的声明中的参数类型列表。

根据C99规范6.9.1/7,只有具有参数类型列表的函数定义才被视为函数原型。K&R样式使用标识符列表代替,因此不被视为具有原型。

不检查对没有原型的函数的函数调用的参数数量或类型(根据6.5.2.2/8,“参数的数量和类型不与不包括函数原型声明符的函数定义中的参数的数量和类型进行比较”)。因此,使用任意数量和类型的参数调用K&R样式中声明的函数是合法的,但根据6.5.2.2/9,使用无效类型的调用将产生未定义的行为。

作为示例,以下代码将在编译时不显示任何警告(在gcc -Wall -Wextra -pedantic -std=c99 -O上):

代码语言:javascript
复制
#include <stdio.h>

void *func(param111)
char *param111;
{
    printf("%s\n", param111);
    return param111;
}

int main()
{
    void *bla0 = func();
    void *bla1 = func(99);
    void *bla2 = func(11111110,99);
    printf("%p, %p, %p\n", bla0, bla1, bla2);
    return 0;
}

尽管显然有不正确的参数类型和计数。

票数 9
EN

Stack Overflow用户

发布于 2013-08-13 15:15:07

它被解释为K&R C,正如其他人所解释的那样。值得注意的是,这在ANSI C中是未定义的行为:

C11 6.9.1函数定义第9节

如果定义的接受可变数目参数的函数没有以省略符号结尾的参数类型列表,则行为未定义。

因此,像printf一样,变量数自变量函数必须以...作为参数结束

代码语言:javascript
复制
int printf( const char *format ,...);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18202232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档