指向结构体的指针是指向其第一个成员的指针吗?

7

我正在学习如何在C语言中使用struct,并编写了以下示例:

#include <stdio.h>
#include <stdlib.h>

struct s1{
    unsigned short member;
};

int main()
{
    struct s1 *s1_ptr = malloc(sizeof(*s1_ptr));
    s1_ptr -> member = 10;
    printf("Member = %d\n", *s1_ptr); // Member = 10
}
问题:在所有情况下,结构体的指针是否保证是指向其第一个元素的完全相同的指针?
在这种特定情况下,它按照我的预期工作,但我不确定是否保证。编译器是否自由地在一开始插入一些填充?
关于结构体类型布局,我能找到的唯一信息是N1570第6.2.5节类型

结构体类型描述了一个顺序分配的非空成员对象集(在某些情况下是不完整的数组),每个对象都有一个可选的名称和可能不同的类型。

但这里没有关于填充的内容。

3
是和不是。指针的类型是不同的,所以不是(它们并不完全相同)。指针所指向的地址是相同的,所以是。请参阅C11 §6.7.2.1结构和联合说明符¶15适当转换后,指向结构对象的指针指向其初始成员(或者如果该成员是位域,则指向其中所在的单元),反之亦然。结构对象内部可能有未命名的填充,但不会出现在其开头。 - Jonathan Leffler
注意你的个人资料图标:请注意,在C++中可能不是这样的... - Aconcagua
2个回答

12

起始处的填充由6.7.2.1p15覆盖(强调我的)

在结构对象中,非位域成员和位域所在的单元的地址按它们声明的顺序递增。指向结构对象的指针,经过适当的转换,指向其初始成员(或如果该成员是一个位域,则指向其所在的单元),反之亦然。结构对象内可能存在未命名的填充,但不能在其开头。

因此,结构体的地址就是其第一个成员的地址。通过指针转换,你能够从一个获得另一个。



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接