从指向结构类型的指针派生的所有指针是否相同的问题不容易回答。我认为这是一个重要问题,主要有以下两个原因:
A。缺少指向“任何”不完整或对象类型的指针,对方便的函数接口施加了限制,例如:
int allocate(ANY_TYPE **p,
size_t s);
int main(void)
{
int *p;
int r = allocate(&p, sizeof *p);
}
指向“任何”不完整或对象类型的现有指针明确描述为:
C99
/ C11
§6.3.2.3 p1
:
指向void的指针可以转换为指向任何不完整或对象类型的指针。 [...]
从指向'any'不完整或对象类型的现有指针派生的指针,指向void的指针,严格来说是指向void的指针,并且不需要使用从指向'的指针派生的指针转换任何'不完整或对象类型。
B. 程序员根据他们对特定实现的经验,使用基于不需要的假设的约定,有意或无意地与指针的泛化相关,这种情况并不少见。假设,例如可转换,可表示为整数或共享公共属性:对象大小,表示或对齐。
根据C99 §6.2.5 p27
/ C11 §6.2.5 p28
:
[...]所有指向结构类型的指针都应具有相同的表示和对齐要求。 [...]
后跟C99 TC3 Footnote 39
/ C11 Footnote 48
:
相同的表示和对齐要求意味着可互换性作为函数的参数,函数的返回值和联合的成员。
虽然标准没有说:“指向结构类型的指针”并且选择了以下单词:“所有指向结构类型的指针”,但它没有明确指定它是否适用于此类的递归派生指针。在标准中提到指针的特殊属性的其他情况下,它没有明确指定或提及递归指针派生,这意味着“类型派生”适用,或者它没有 - 但它没有明确提及。 / p>
虽然在引用类型时使用的语句“所有指针”仅使用两次,(对于结构和联合类型),而不是更明确的措辞:“指向”在整个标准中使用,我们不能断定它是否适用于这种指针的递归推导。
答案 0 :(得分:1)
我的回答是“不。”
我知道C的任何标准都没有措辞,否则就是这样。所有指向结构类型的指针具有相同的表示和对齐要求这一事实与任何派生类型无关。
这完全有道理,任何其他现实似乎都是不一致的。考虑替代方案:
让我们调用指向结构类型“A”的指针的对齐和表示要求。假设任何“递归派生类型”共享要求“A”。
让我们调用指向联合类型“B”的指针的对齐和表示要求。假设任何“递归派生类型”共享要求“B”。
让我们假设“A”和“B”不一样[1]。而且,让我们假设它们不能同时满足。 (例如,4字节表示和8字节表示。)
现在从两个派生出一个类型:
现在你有一个不能满足要求的类型,因为它必须满足“A”和“B”,但它们不能同时满足。
也许你认为派生类型具有平坦的血统,一直回到单个祖先,但事实并非如此。派生类型可以有许多祖先。 “派生类型”的标准定义讨论了这一点。
[1]虽然这似乎是不合理的,不太可能和愚蠢,但这是允许的。