Min*_*s97 6 c inheritance struct pointers strict-aliasing
如果有人回答我的问题,请不要告诉我使用C++.
所以,我在C中创建了一个使用面向对象方法的小型库.我选择在C中使用两种主要的继承方法中较不常见的方法:将基类型的成员复制到派生类型的开头.像这样的东西:
struct base {
int a;
int b;
char c;
};
struct derived {
int a;
int b;
char c;
unsigned int d;
void (*virtual_method)(int, char);
};
Run Code Online (Sandbox Code Playgroud)
这种方法不如另一种方法(基类型的实例作为派生类型的第一个成员)受欢迎,因为
但是,与其他方法相比,它也有其优点:
我一直在寻找使我的库编译和使用强制执行严格别名(如gcc)的编译器正确工作的可能性,而无需用户手动关闭它.以下是我研究过的可能性:
工会.遗憾的是,由于以下几个原因,这些是禁忌:
使用memcpy而不是直接解除引用(如此处).这看起来是个不错的解决方案.但是,函数调用会产生开销,是的,再一次,冗长.据我所知,memcpy也可以通过将指向结构的指针强制转换为指针char然后解除引用来手动完成,如下所示:(member_type)(*((char*)(&struct_pointer->member))) = new_value;Gah,再次详述.好吧,这可以用宏包裹.但是,如果我们将指针转换为指向不兼容类型的指针,然后将其转换为char*并取消引用它,那么它仍然可以工作吗?像这样:(member_type)(*((char*)(&((struct incompatible_type*)struct_pointer)->member))) = new_value;
声明我们将要转换为的所有类型实例volatile.我想知道为什么这不经常出现.volatile据我所知,用于告诉编译器指针指向的内存可能会意外更改,从而根据假定一段指向内存不会发生变化取消优化,这是所有原因严格别名问题.当然,这仍然是未定义的行为; 但对于某些类型的某些实例的"hackishly"禁用严格的别名优化,它不是一个可行的跨平台解决方案吗?
除了上面的问题,还有两个:
我不认为你关于通过投射的想法char*是有效的。规则是:
对象的存储值只能由具有以下类型之一的左值表达式访问
表达式的子表达式是兼容的,但整个表达式不兼容。
我认为唯一现实的方法是组合:
struct base {
int a;
int b;
char c;
void (*virtual_method)(base*/*this*/,int, char);
};
struct derived {
struct base;
unsigned int d;
};
Run Code Online (Sandbox Code Playgroud)
我意识到这是一种在智力上没有吸引力的实现继承的方式。
PS:我还没有把你的虚拟成员函数指针放在我的派生类中。它需要可以从baseso 访问,因此需要在那里声明(假设它是 和 都存在的多态函数base)derived。我还添加了一个this参数来充实模型。