【问题标题】:C : differences between prototype declaration in header and function declaration for implementation?C:标头中的原型声明和实现的函数声明之间的区别?
【发布时间】:2009-04-05 16:05:28
【问题描述】:

我想知道在头文件和 .c 文件中声明函数原型之间的细微差别。我有一个带有一些原型函数的头文件和一个带有这些函数的实际实现的一些 .c 文件。我在标题中做了一些更改,只添加了“__restrict”限定符(由 gcc 识别)。我的问题是我是否必须将“__restrict”限定符放入 .c 文件中(目前代码已编译,所以我猜答案是否定的,但希望能提供一些精确度)。

这对每个 C 限定符都有效吗?我可以在标题中添加一些“const”或“volatile”而不必在 .c 文件中执行相同的操作吗?

目前在标题中:

int myfunc_gettype (const mytype *__restrict, int *__restrict);

在实现文件中:

int myfunc_gettype(const mytype *attr, int *type)

【问题讨论】:

    标签: c prototype declaration


    【解决方案1】:

    必须。不匹配会调用未定义的行为。是否有某些原因需要在标题和定义中分别声明?

    请注意,关键字是restrict,而不是__restrict,后者是供应商扩展名(提示:查看关键字名称前的_)。您应该坚持使用标准版本的可移植性。

    【讨论】:

    • 事实上,restrict 关键字是 C99,而 __restrict 只是被 gcc 捕获,我猜结果相同。
    • 我不确定是否理解,如果我在标头中而不是在实现中具有限制限定符,那么指针是否仍然是“限制”?
    • 您正在调用 UB。它实际上可能导致指针被限制限定。标准 C++ 关键字是 'restrict',为什么要使用 __restrict?
    • restrict 关键字是指针的类型限定符,是 C99 标准的正式部分。在无法用 C99 编译的代码中,使用 restrict 或 __restrict 来启用关键字作为 GCC 扩展。
    • 我的库有一个头文件,每个函数有一个 .c 文件,所以我想知道是否可以避免修改每个 .c 文件(这是很多文件)而只修改标题仅限。
    【解决方案2】:

    使用gcc 4.0.1,这取决于const是否无意义:

    // Who cares, compiles fine, but irks the maintenance programmer.
    
    // f.h
    int f(const int i);
    
    // f.c
    int f(int i) { return i += 42; }
    
    
    // No no no no Your Types Conflict gcc will not stand for it
    
    // f.h
    int f(const int *pi);
    
    // f.c
    int f(int *pi) { return (*pi)+= 42; }
    

    【讨论】:

    • 问题不是“这是否合法”,甚至不是“这是可接受的做法”;它是“它会工作。”
    【解决方案3】:

    注意:您实际上并未添加“限制”限定符。你只是在原型中有不同的(可选的)变量名。

    至于您的问题,如果实现中#included 不匹配的原型,大多数优秀的 C 编译器都会捕获此错误并引发警告/错误。如果您的原型不匹配,您可能会看到从细微到即时崩溃的各种问题。

    【讨论】:

    • 你的意思是 __restrict 是原型中的可选变量名?我很确定你对 gcc 有误。
    • 其实我是对的:“restrict关键字是指针的类型限定符,是C99标准的正式部分。在不能用C99编译的代码中,使用restrict或 __restrict 以启用关键字作为 GCC 扩展。"
    • 既然可以编译,肯定只是限定符;你不能有两个同名的参数。起初我想知道,但我认为这个论点是决定性的 - 假设代码确实按要求编译。
    • @Jonathan :是的,在使用 __restrict 限定符之前,我首先使用了没有 -std=c99 的限制,而 gcc 抱怨有两个同名的参数,然后我记得我无法使用 - 进行编译暂时 std=c99 并决定使用 gcc 扩展 __restrict。
    猜你喜欢
    • 2017-10-02
    • 2011-09-20
    • 1970-01-01
    • 2015-10-20
    • 2020-06-07
    • 1970-01-01
    • 2012-07-15
    • 2020-04-20
    • 1970-01-01
    相关资源
    最近更新 更多