Question

I have a c++ library with a callback based C API. A callback type looks like this:

typedef struct {...} Result;
typedef void (*callback) (const Result* result, void* userData);

The user can register a callback like this, and can set a pointer to arbitrary data, and the library will pass that pointer back trough the callback.

My main concern here is: Is it violate the strict aliasing rule or not? Do I need to change the type of the userData to char*?

Was it helpful?

Solution

No, aliasing only applies when pointers are indirected, not when they are passed as pointer values. As long as the user behaves consistently you'll be fine.

That is, the user must ensure that if they pass userData of actual type T, then they always cast it to T * in the callback function before accessing it.

I'm assuming of course that you're not indirecting userData in your library, although again accessing it as a pointer (e.g. printf("DEBUG: %p", userData)) is fine.

OTHER TIPS

You could create a more "C++"-ish interface for the C callback API, that might remove your aliasing concern.

struct Callback {
    void (*callback) (Callback *cb_this, const Result *result);
};

A C programmer using your C callback API to register a callback would do something like this:

struct MyCallback {
    struct Callback cb;
    int x;
    double y;
    /* ... */
};

void my_callback_func (Callback *cb_this, const Result *result) {
    MyCallback *my_cb = (MyCallback *)cb_this;
    /* ... */
}

MyCallback mycb = { { my_callback_func }, 0, 0, /* ... */ };

This way you don't have to worry about handling a void *. Instead, you are passed a single pointer to a Callback.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top