因此,严格的别名规则明确允许以下几种情况(为了清楚起见,让我们在C23中这样做):
第一点也是最明显的一点是,允许 struct 使用指向其初始成员的指针作为别名:
typedef struct {
int data;
} parent;
typedef struct {
parent _base;
int metadata;
} child;
int main() {
child child_obj = {};
parent* parent_ptr = (parent*) &child_obj; // Fine to read and write
int* int_ptr = (int*) parent_ptr; // Also fine
}
第二,具有公共初始序列的对象的联合允许访问那些公共元素,并且指向联合的指针可以自由地转换为/作为指向其任何元素的指针来访问.
typedef struct {
int type_id;
size_t size;
char* buffer;
} dynamic_string;
typedef struct {
int type_id;
size_t number;
} just_a_number;
typedef union {
dynamic_string dystr;
just_a_number num;
struct {
int type_id;
char fixed_string[32];
};
} string_or_num;
int main() {
string_or_num obj = {};
if(obj.type_id == 2) // Fine, common initial sequence
memcpy("Hello World!", obj.fixed_string, 13);
// Fine
dynamic_string* ds_ptr = (dynamic_string*) &obj;
just_a_number* num_ptr = (just_a_number*) &obj;
// Also fine, pointer to initial common member
int* int_ptr = (int*) &obj;
}
直觉上,我认为我可以将这些组合成如下所示.然而,我对我的标准不够有信心,不能百分百肯定地说这是犹太教的
typedef struct {
int type_id;
char data[4];
} parent_a;
typedef struct {
int type_id;
float decimal;
} parent_b;
// No initial sequence
typedef struct {
double ccccombo_breaker;
} parent_c;
typedef struct {
union {
parent_a _base_a;
parent_b _base_b;
parent_c _base_c;
};
int look_at_me_ive_got_three_parents;
} child;
int main() {
child child_obj = {};
// Are these kosher?
parent_a* a_ptr = (parent_a*) &child_obj;
parent_b* b_ptr = (parent_b*) &child_obj;
// How about this?
parent_c* c_ptr = (parent_c*) &child_obj;
double* db_ptr = (double*) &child_obj;
}
需要澄清的是,我并不是在问parent_c
是不是一个好主意,而是问标准是怎么说的.通过这些指针进行的读取和写入是否遵循别名规则?
如果你有来自标准的准确语言或标准部分的组合,从而构成令人信服的理由,那么你就会获得加分.