【问题标题】:Warning about function prototype even when the function takes arguments即使函数带有参数,也会发出关于函数原型的警告
【发布时间】:2015-03-15 12:34:58
【问题描述】:

我在 C 中有一个简单的函数,它接受 int* 参数,并且我在头文件中声明了它,如下所示:

void mapAuditFioError(int *errno);

但编译器会按如下方式编译包含此标头的文件:

"warning: function declaration isn't a prototype"

还有:

"warning: passing argument 1 of 'mapAuditFioError' from incompatible pointer type"

即使我用一个整数指针本身来调用它。

浏览这个警告总是谈论这样的函数:int func() 实际上应该声明为int func(void)。但是我上面的函数有什么问题?

【问题讨论】:

    标签: c compiler-warnings function-prototypes


    【解决方案1】:

    这是因为errno 是 C 语言中的 reserved name(独立实现除外),用于从标准库函数传达错误条件。正如 glibc 文档所说:

    所有库类型、宏、变量和函数的名称 来自ISO C标准的无条件保留; 你的 程序可能不会重新定义这些名称。所有其他库名称是 如果您的程序明确包含以下头文件,则保留 定义或声明它们。

    您不能使用errno 作为变量名。它可以被声明为一个宏,而且通常是这样。

    例如,在我的 Linux 上的 GCC 和 glibc 上,如果我在原型前加上 <stdio.h>

    void foo(int *errno);
    

    被预处理成

    void foo(int *(*__errno_location ()));
    

    现在,它编译时没有警告,因为它是一个合法的构造;在您的 C 编译器上,errno 的行为有所不同。


    要修复它,请将您的参数称为其他名称,例如 errcodeerror_number


    <errno.h> 上的 C11 标准 N1570 委员会草案 7.5 明确指出

    如果为了访问实际对象或程序而禁止宏定义 用名称定义标识符 errno行为未定义

    【讨论】:

    • 要修复,请调用errno以外的参数
    • 我想应该是“...如果我包括<errno.h>...”。 Afaik,<stdio.h> 不能定义 errno
    • @mafso 所有这些名称都是保留的,即使您没有包含应该定义这些名称的标题。
    • 我的答案中的代码来自gcc -E 输出,我只明确包含<stdio.h>
    • @AnttiHaapala 我不知道,现在接受了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 2017-07-17
    相关资源
    最近更新 更多