Search code examples
ctype-conversionheader-filesvoid-pointers

Is it worthwhile changing a C declaration to add type safety?


I'm wondering is it reasonable, or worthwhile, overriding header declarations in order to set a particular type. In preference to something like void * which adds no type safety.

For example, if you have a generic storage function that adds a sensor reading to a circular buffer:

int add_reading(void *);

In order to be generic, the function has to be defined as a void *. However, in the header file, you could declare the function as:

int add_reading(my_reading_t *);

which would add a degree of type safety over the void pointer. In a generic header, you could set the type with a #define that defaulted to void. Thus the override type could be defined just before the #include.

It seems an unnecessary hack, but one could argue the same for opaque pointers too - using opaque_type_t * in preference to void *. But that at least is defined behaviour. What I wonder is if this type of messing invokes UB (undefined behaviour)?


Solution

  • A function declared with int add_reading(void *) is not compatible with a function defined with int add_reading(my_reading_t *). The behavior of calling a function defined with the latter using an identifier declared with the former (or other function designator with that type) will not be defined by the C standard, per C 2018 6.5.2.2 9:

    If the function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function, the behavior is undefined.

    Per 6.7.6.1 2:

    For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.

    Obviously, the parameter types void * and my_reading_t * are not pointers to compatible types (presuming my_reading_t is a structure type, is not an alias for void).

    Per 6.7.6.3 15:

    For two function types to be compatible,… corresponding parameters shall have compatible types…