Dro*_* K. 11 c struct pointers strict-aliasing language-lawyer
根据两者C99 §6.2.5p27和C11 §6.2.5p28:
所有指向结构类型的指针都应具有相同的表示和对齐要求.
用脚注(#39和#48分别):
相同的表示和对齐要求意味着可互换性作为函数的参数,函数的返回值和联合的成员.
(注意,C89 §3.1.2.5没有指定关于结构的指针)
-
众所周知,指向void的指针,例如C11 §6.3.2.3p1:
A pointer to void may be converted to or from a pointer to any object type.
Run Code Online (Sandbox Code Playgroud)
并不意味着指向void的指针与指向void的指针相同,并不意味着与指向数据对象的指针的其他指针相同.
(如果我过于宽泛地使用"隐含相同"一词,我会道歉,它只能在指定的上下文中使用)
以下是演示指向struct的指针的通用指针的代码示例:
#include <stdio.h>
#include <stdlib.h>
int allocate_struct(void *p, size_t s) {
struct generic { char placeholder; };
if ( ( *(struct generic **) p = malloc(s) ) == NULL ) {
fprintf(stderr, "Error: malloc();");
return -1;
}
printf("p: %p;\n", (void *) *(struct generic **) p);
return 0;
}
int main(void) {
struct s1 { unsigned int i; } *s1;
if (allocate_struct(&s1, sizeof *s1) != 0)
return -1;
printf("s1: %p;\n\n", (void *) s1);
s1->i = 1;
free(s1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC:
-std=c89 -pedantic-errors -Wall -Wextra -fstrict-aliasing -Wstrict-aliasing=3 -O3
Run Code Online (Sandbox Code Playgroud)
结果:(没有警告)
p: 0x800103a8;
s1: 0x800103a8;
Run Code Online (Sandbox Code Playgroud)
.
指向结构的指针隐含的可互换性是否同样适用于指向结构指针的指针?
只是为了澄清:问题是关于struct x **VS等struct y **,而不是struct x *VS struct y **.
x**与类型级别不同y**,第一个引用是谈论指针与其类型相比的大小。
一个指针可以从 x* 转换为 void* ,说“谁关心这是什么”,这样你就可以将它作为内存地址传递,并且你告诉编译器,相信我我知道我在做什么。
一旦你告诉编译器闭嘴,我知道我在做什么,而你犯了一个错误,你就得靠你自己了。