cpowerpccodewarrior

Using a void* as an argument inside a function pointer inside a structure definition causes a syntax error


I am creating an interface structure

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;

My question is when I try to compile why using void* as a function argument it throws a syntax error.

if I use a typedef typedef void* VoidPtr

and then use

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;

everything complies just fine.

Does anyone have a clue while this is happening? Thanks in advance.


Solution

  • This member declaration

    U8 (*Put)(Circular_Buffer, VoidPtr);
    

    will work fine if neither Circular_Buffer nor VoidPtr are defined with typedef at that point in the source code. (U8 must be defined, though.) That's because it will be accepted as a K&R-style function declaration which specifies the names of the parameters but not their types. (That is, Put will be declared as a pointer to a function taking two parameters of unspecified type.)

    It will also work if both Circular_Buffer and VoidPtr are defined as typedefs, in which case it will be treated as a normal standard C declaration.

    If you compile with -Wall, the first case will probably produce a warning. -Wall is always recommended.

    It should fail to compile if only one of the two identifiers is declared as a typedef, so I don't know how it works in the case where typedef void* VoidPtr comes before the member declaration, and typedef struct ... Circular_Buffer comes afterwards. Perhaps that's an obscure feature of an old version of gcc. (Once the compiler decides it is a K&R function declaration, the actual parameter names can be ignored unless the it is a function definition, and in the context in which the line appears, it cannot be a function definition.)