C 是否保证所有指针都能正确往返于void*中?

C 是否保证所有指针都能正确往返于void*中?,c,pointers,language-lawyer,void-pointers,C,Pointers,Language Lawyer,Void Pointers,在C语言中,是否保证任何指针类型都可以成功地往返于void* 也就是说,类似于以下的东西保证会起作用: typedef struct { ... } A; A *p = ...; void *v = p; A *p2 = v; // use p2 here 无论A的类型是什么?对象指针确实可以通过void*进行往返。根据C11 6.3.2.3第1段: 指向void的指针可以转换为指向任何对象类型的指针,也可以转换为指向任何对象类型的指针。指向 任何对象类型都可以转换为指向void并返回的指针

在C语言中,是否保证任何指针类型都可以成功地往返于
void*

也就是说,类似于以下的东西保证会起作用:

typedef struct {
...
} A;

A *p = ...;
void *v = p;
A *p2 = v;
// use p2 here

无论
A
的类型是什么?

对象指针确实可以通过
void*
进行往返。根据C11 6.3.2.3第1段:

指向void的指针可以转换为指向任何对象类型的指针,也可以转换为指向任何对象类型的指针。指向 任何对象类型都可以转换为指向void并返回的指针;结果将是 比较等于原始指针

请注意,相反的方向不是真的,当您将一个空指针转换为某个对象指针并返回时,不能保证与开始时的值相同

还要注意的是,函数指针并非如此;但是,所有函数指针类型都是可相互旋转的:第8段说:

指向一种类型函数的指针可以转换为指向另一种类型函数的指针 再次输入并返回;结果应与原始指针进行比较

此外,根据第7段的规定,对象指针在它们之间也是可旋转的(不包括空指针),受一些约束:

指向对象类型的指针可以转换为指向不同对象类型的指针。如果引用类型的结果指针未正确对齐),则行为未定义。否则,当再次转换回时,结果应与原始指针进行比较


对象指针确实可以通过
void*
进行往返。根据C11 6.3.2.3第1段:

指向void的指针可以转换为指向任何对象类型的指针,也可以转换为指向任何对象类型的指针。指向 任何对象类型都可以转换为指向void并返回的指针;结果将是 比较等于原始指针

请注意,相反的方向不是真的,当您将一个空指针转换为某个对象指针并返回时,不能保证与开始时的值相同

还要注意的是,函数指针并非如此;但是,所有函数指针类型都是可相互旋转的:第8段说:

指向一种类型函数的指针可以转换为指向另一种类型函数的指针 再次输入并返回;结果应与原始指针进行比较

此外,根据第7段的规定,对象指针在它们之间也是可旋转的(不包括空指针),受一些约束:

指向对象类型的指针可以转换为指向不同对象类型的指针。如果引用类型的结果指针未正确对齐),则行为未定义。否则,当再次转换回时,结果应与原始指针进行比较


只有对象指针。不是函数指针。是的,不要将函数强制转换为
void*
,您应该将其包装在结构中,仅对象指针。不是函数指针。是的,不要将函数强制转换为
void*
,你应该将它包装在一个结构中,建议详细说明通过
void*
往返产生一个等价的指针,但不一定是相同的位模式指针。IAC,OP似乎只对等效访问感兴趣。指向任何类型的指针都可以转换为任何其他类型并返回,只要不违反对齐方式,它将与原始指针进行比较。@2501:需要引用。请阅读第7段。@2501:啊,是的,确实如此。建议详细说明通过
void*
往返产生一个等效指针,但不一定是相同的位模式指针。IAC,OP似乎只对等效访问感兴趣。指向任何类型的指针都可以转换为任何其他类型并返回,只要不违反对齐方式,它将与原始指针进行比较。@2501:需要引用。请阅读第7段。@2501:啊,是的,确实如此。