强制转换GLib/GTK指针是未定义的行为吗



由于C不支持继承,GLib/GTK通过将基类对象作为派生类对象的第一个成员来模拟它。我想是这样的:

struct Parent
{
//...
};
struct Child
{
Parent base;
//...
}

然后我们可以将子结构指针强制转换为父结构指针:

Child  *p_child  = make_child();
Parent *p_parent = (Parent*)p_child;

在C++中,可以使用reinterpret_cast:

Parent *p_parent = reinterpret_cast<Parent*>(p_child);

但据我所知,这是UB,因为Child和Parent是不相关的类。

它在C++中是未定义的行为吗?它是C中未定义的行为吗?

GLib/GTK中,有转换宏:

GtkWindow *p_window = ...;
GtkWidget *p_widget = GTK_WIDGET(p_window);

我不知道他们到底在做什么。他们是否使用了一些特殊的操作来定义铸造行为?

注意:这个答案只针对问题的C部分

这是C中未定义的行为吗?

不,将指向结构的指针转换为与结构的第一个元素类型相同的指针是合法的。

由于缺少struct关键字,您的代码不是有效的C,但原理很好。这样的代码在C:中有效

struct Parent
{
int id;
}
struct Child
{
struct Parent parent;
int n;
}
struct Child * c = malloc(sizeof *c);
struct Parent * p = (struct Parent*)c;  // Valid because the first member of 
// struct Child is a struct Parent
p->id = 42;
printf("%dn", c->parent.id;  // Will print 42

最新更新