我正在创建一个界面结构
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;
一切都顺利。
有人在发生这种情况时有线索吗? 提前谢谢。
答案 0 :(得分:2)
此会员声明
U8 (*Put)(Circular_Buffer, VoidPtr);
如果源代码中的Circular_Buffer
和VoidPtr
都没有定义typedef
,则将正常工作。 (U8
必须定义。)那是因为它将被接受为K& R风格的函数声明,它指定参数的名称而不是它们的类型。 (也就是说,Put
将被声明为指向带有两个未指定类型参数的函数的指针。)
如果Circular_Buffer
和VoidPtr
都被定义为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编译器上,而不是你的代码。