考虑以下同构结构:
struct myStruct {
void* a;
char* b;
int* c;
};
Run Code Online (Sandbox Code Playgroud)
我相信它是同类的,因为所有的数据类型都是指针.
鉴于此结构,以下代码在C99中是否有效且可移植?
int main()
{
void* x = NULL;
char* y = "hello";
int* z = malloc(sizeof(int) * 10);
z[2] = 10;
void** myArray = malloc(sizeof(void*) * 3);
myArray[0] = x;
myArray[1] = y;
myArray[2] = z;
struct myStruct* s = (struct myStruct*)myArray;
printf("%p %s %d\n", s->a, s->b, s->c[2]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道结构通常会在组件之间添加填充以保持结构的大小一致,但是,因为指针的类型都是相同的,是否可以安全地假设不添加填充?我不一定要问是否有100%的保证(我明白这完全是特定于实现的,并且编译器可能因为不明原因而添加填充),更多我要求填充可能添加到同构结构的原因,如有任何理由的话.
Som*_*ude 19
不,它不便携.指针的大小实际上可能不同,这意味着您的结构中可能存在填充.
在大多数现代平台上,这不会成为问题,但标准中没有任何内容表明所有指针的大小必须相同.只有那些指针可以隐式转换为和转换void *.
指针大小不同的平台的一个很好的例子是DOS(仍在主动使用,例如在嵌入式系统上)和其他16位分段系统.
250*_*501 12
代码违反了别名规则.void*和struct myStruct类型不兼容,在这种情况下没有例外.printf语句中的struct指针的取消引用会导致未定义的行为:
printf("%p %s %d\n", s->a, s->b, s->c[2]);
Run Code Online (Sandbox Code Playgroud)
即使结构与三个void指针具有相同的大小,没有填充,并且具有相同的对齐要求,也是如此.