Hacker News new | ask | show | jobs
by layer8 617 days ago
There is no problem with using the typedef struct trick. The problem is assuming that such pointers have the same underlying representation as void pointers. Structs typically having stricter alignment requirements (whereas void* must be able to point to any byte) is one reason why their representation may differ from void*. This is why only [[un]signed] char* is guaranteed to have the same representation as void*.

Given:

    typedef struct foo Foo:
    Foo * createFoo();
    void useFoo(Foo * foo);

    Foo * foo = createFoo();
    void * vp = foo;
This is perfectly fine:

    useFoo((Foo *) vp);
This is not:

    void (*)(void *) vf = (void (*)(void *)) useFoo;
    (*fv)(vp);
1 comments

Alignment only matters when you use a pointer. This is a question of if technically non compatible signatures are UB by them selves. Unaligned access is UB for sure, but even if everything is perfectly aligned they may still be UB according to the standard.

Example:

Lets say you have a function that takes a pointer to a 32 bit integer.

void my_function(int x)

But in an other file you declare it as a function taking a 32 bit float, and call it:

extern void my_function(float x); ... my_function(&my_float);

This is very likely to work in almost all implementations. float and int have the same size and same alignment requirements, but the standard may still say its UB. So it is technically UB, but may be relied upon in practice.