使用用户数据严格别名和回调

时间:2012-06-12 10:52:35

标签: c++ strict-aliasing

我有一个带有基于回调的C API的c ++库。回调类型如下所示:

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

用户可以注册这样的回调,并可以设置指向任意数据的指针,并且库将通过回调传递该指针。

我主要担心的是: 是否违反了严格的别名规则?我是否需要将userData的类型更改为char *?

2 个答案:

答案 0 :(得分:4)

不,别名仅在指针间接指示时适用,而不是在指针作为指针值传递时。只要用户表现得一致,你就可以了。

也就是说,用户必须确保如果他们通过userData实际类型T,那么他们总是在访问回调函数之前将其转换为T *

我当然假设你没有在你的图书馆中间接userData,尽管再次将其作为指针访问(例如printf("DEBUG: %p", userData))也没问题。

答案 1 :(得分:0)

您可以为C回调API创建更多“C ++” - ish界面,这可能会消除您的别名问题。

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

使用C回调API注册回调的C程序员可以这样做:

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, /* ... */ };

这样您就不必担心处理void *了。而是通过单个指针传递给Callback