Jon*_*ger 2 c oop struct pointers
我编写了以下代码并且它可以工作,但我想知道是否可以确保它在所有x86机器上始终有效.
#include <stdio.h>
#include <stdlib.h>
typedef struct Base {
int a;
float b;
} Base;
typedef struct Derived1 {
int a; // This two members have the same position as in the Base
float b;
// adding some other members to this struct
int otherMember;
int otherMember2;
} Derived1;
int main()
{
Base *bases[2];
// Filling the array with different structs
bases[0] = (Base*) malloc(sizeof(Base));
bases[1] = (Base*) malloc(sizeof(Derived1));
bases[1]->a = 5;
Derived1 *d1 = (Derived1*) bases[1];
if(d1->a == 5)
printf("SUCCESS\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道为什么这个例子有效,但它总能工作吗?是否有填充或类似的东西可以防止这种情况,或者C标准是否支持这个?
根据C99规则,这两个struct是不兼容的:
如果它们的标记和成员满足以下要求,则在单独的转换单元中声明的两个结构,联合或枚举类型是兼容的:如果使用标记声明一个,则另一个应使用相同的标记声明.如果两者都是完整类型,则以下附加要求适用:其成员之间应存在一对一的对应关系,使得每对相应成员都声明为具有兼容类型,并且如果相应对的一个成员是使用名称声明,另一个成员使用相同的名称声明.对于两个结构,相应的成员应按相同的顺序声明.
您的代码在成员之间断开了一对一的对应关系,因此根据标准,这将是无效的:
Base *d1 = (Base*) bases[1];
d1->a=5; // Not valid
Run Code Online (Sandbox Code Playgroud)
幸运的是,您可以通过嵌入Base到Derived1以下内容轻松使其有效:
typedef struct Derived1 {
Base base;
// adding some other members to this struct
int otherMember;
int otherMember2;
} Derived1;
Run Code Online (Sandbox Code Playgroud)
根据C99,
指向适当转换的结构对象的指针指向其初始成员
因此,这是有效的:
Base *d1 = (Base*) bases[1];
d1->a=5; // Valid
Run Code Online (Sandbox Code Playgroud)
注意: 此问答讨论了严格别名的相关主题.
| 归档时间: |
|
| 查看次数: |
94 次 |
| 最近记录: |