在结构定义内的函数指针内使用void *作为参数会导致语法错误

时间:2015-11-11 20:48:32

标签: c powerpc codewarrior

我正在创建一个界面结构

typedef struct Circular_Buffer_Interface_t * Circular_Buffer_Interface;
typedef struct Circular_Buffer_Interface_t {
    U8 (*Put)(Circular_Buffer, void*);
    U8 (*Get)(Circular_Buffer, void*);
    U8 (*Reset)(Circular_Buffer);
    BOOL (*isFull)(Circular_Buffer);
    BOOL (*isEmpty)(Circular_Buffer);
} Circular_Buffer_Interface_t;

typedef struct Circular_Buffer_t * Circular_Buffer;
typedef struct Circular_Buffer_t {
    Circular_Buffer_Interface Interface;
} Circular_Buffer_t;

我的问题是当我尝试编译为什么使用void *作为函数参数时会抛出语法错误。

如果我使用typedef    typedef void* VoidPtr

然后使用

typedef void* VoidPtr;
typedef struct Circular_Buffer_Interface_t {
    U8 (*Put)(Circular_Buffer, VoidPtr);
    U8 (*Get)(Circular_Buffer, VoidPtr);
    U8 (*Reset)(Circular_Buffer);
    BOOL (*isFull)(Circular_Buffer);
    BOOL (*isEmpty)(Circular_Buffer);
} Circular_Buffer_Interface_t;

一切都顺利。

有人在发生这种情况时有线索吗? 提前谢谢。

2 个答案:

答案 0 :(得分:2)

此会员声明

U8 (*Put)(Circular_Buffer, VoidPtr);
如果源代码中的Circular_BufferVoidPtr都没有定义typedef,则

将正常工作。 (U8必须定义。)那是因为它将被接受为K& R风格的函数声明,它指定参数的名称而不是它们的类型。 (也就是说,Put将被声明为指向带有两个未指定类型参数的函数的指针。)

如果Circular_BufferVoidPtr都被定义为typedef,它也会有效,在这种情况下,它将被视为普通的标准C声明。

如果使用-Wall进行编译,第一种情况可能会产生警告。 -Wall 总是推荐。

如果两个标识符中只有一个被声明为typedef,则编译失败,所以我不知道在成员声明之前typedef void* VoidPtr出现的情况下它是如何工作的, typedef struct ... Circular_Buffer之后来了。也许这是旧版gcc的一个模糊特征。 (一旦编译器确定它是K& R函数声明,除非它是函数定义,否则可以忽略实际参数名称,并且在行出现的上下文中,它不能是函数定义。)

答案 1 :(得分:0)

使用void *的第一个声明似乎完全有效C.我添加了一些代码,使其成为一个完整的程序:

#include <stdio.h>

typedef int U8;
typedef int BOOL;
typedef int Circular_Buffer;

typedef struct Circular_Buffer_Interface_t {
    U8 (*Put)(Circular_Buffer, void*);
    U8 (*Get)(Circular_Buffer, void*);
    U8 (*Reset)(Circular_Buffer);
    BOOL (*isFull)(Circular_Buffer);
    BOOL (*isEmpty)(Circular_Buffer);
} Circular_Buffer_Interface_t;

int main() {
    puts("hello");
}

此程序在MacOSX上成功编译并且没有警告使用GNU C 5.2:

> gcc-5 -std=c99 -Wall x.c
> ./a.out
hello

同样适用于Apple版的clang。因此,我怀疑问题出在你的C编译器上,而不是你的代码。