C 你能给彼此分配不同类型的指针吗?

C 你能给彼此分配不同类型的指针吗?,c,pointers,C,Pointers,考虑到 T1 *p1; T2 *p2; 我们可以将p1分配给p2吗?反之亦然?如果是这样,是否可以不使用强制类型或我们必须使用强制类型?当类型T1和T2不同时,T1*p1和T2*p2之间的赋值被正式禁止,除非T1和T2中至少有一个是void,另一个是对象(非函数)类型 在许多情况下,不兼容的赋值在实践中会起作用,特别是在具有“扁平”地址空间且所有指针类型共享相同内部表示的机器上(例如今天所有流行的机器) 然而,在“混合模式”指针分配之后,由于(1)对齐问题和(2)取消引用指针时,很可能会出现问

考虑到

T1 *p1;
T2 *p2;

我们可以将p1分配给p2吗?反之亦然?如果是这样,是否可以不使用强制类型或我们必须使用强制类型?

当类型
T1
T2
不同时,
T1*p1
T2*p2
之间的赋值被正式禁止,除非
T1
T2
中至少有一个是
void
,另一个是对象(非函数)类型

在许多情况下,不兼容的赋值在实践中会起作用,特别是在具有“扁平”地址空间且所有指针类型共享相同内部表示的机器上(例如今天所有流行的机器)

然而,在“混合模式”指针分配之后,由于(1)对齐问题和(2)取消引用指针时,很可能会出现问题

由于“混合模式”指针分配在形式上是非法的,而且通常是一个坏主意,大多数编译器都会对此发出警告。大多数编译器允许使用显式强制转换来抑制警告。大多数情况下,演员阵容只起到压制警告的作用;它不会引入任何实际的转换,而这些转换无论如何都不会被执行。(也就是说,将
p1=p2
更改为
p1=(T1*)p2
非常类似于将
i=f
更改为
i=(int)f
,其中
i
是一个int,而
f
是一个浮点。)



附录:我写道,“当类型
T1
T2
不同时”,但更准确的说法是当它们不兼容时。例如,类型
char
unsigned char
是兼容的,因此这些类型的指针之间的赋值是可以的。有关更多详细信息,请参见Eric Postpuschil的较长答案。

当类型
T1
T2
不同时,
T1*p1
T2*p2
之间的赋值被正式禁止,除非
T1
T2
中至少有一个是
void
且另一个是对象(非函数)类型

在许多情况下,不兼容的赋值在实践中会起作用,特别是在具有“扁平”地址空间且所有指针类型共享相同内部表示的机器上(例如今天所有流行的机器)

然而,在“混合模式”指针分配之后,由于(1)对齐问题和(2)取消引用指针时,很可能会出现问题

由于“混合模式”指针分配在形式上是非法的,而且通常是一个坏主意,大多数编译器都会对此发出警告。大多数编译器允许使用显式强制转换来抑制警告。大多数情况下,演员阵容只起到压制警告的作用;它不会引入任何实际的转换,而这些转换无论如何都不会被执行。(也就是说,将
p1=p2
更改为
p1=(T1*)p2
非常类似于将
i=f
更改为
i=(int)f
,其中
i
是一个int,而
f
是一个浮点。)



附录:我写道,“当类型
T1
T2
不同时”,但更准确的说法是当它们不兼容时。例如,类型
char
unsigned char
是兼容的,因此这些类型的指针之间的赋值是可以的。请参阅Eric Postpischil更详细的答案。

首先,让我们考虑没有浇铸的作业。C 2018 6.5.16.1 1列出了简单分配的约束条件,表示其中一项必须保持不变。前两个用于算术、结构和联合类型。最后两项交易涉及空指针常量或

\u Bool
。中间两个用于将指针分配给指针:

  • 左操作数具有原子、限定或非限定指针类型,并且…两个操作数都是指向兼容类型的限定或非限定版本的指针,而左指向的类型具有右指向的类型的所有限定符

  • 左操作数具有原子、限定或非限定指针类型,并且…一个操作数是指向对象类型的指针,另一个操作数是指向void的限定或非限定版本的指针,左指向的类型具有右指向的类型的所有限定符

后者表示只要不删除限定符(
const
volatile
restrict
、或
\uu-Atomic
),我们就可以将
void*
分配给任何对象指针,反之亦然

前者说,只要不删除任何限定符,我们就可以将指针分配给兼容的类型。什么是兼容类型

6.2.7.1规定:

  • 如果两种类型相同,则它们是兼容的
  • 其他规则见6.7.2、6.7.3和6.7.6
  • 在单独的翻译单元中声明的两个结构、联合或枚举类型,如果本质上声明相同,则它们是兼容的。(有趣的是,在相同的翻译单元中声明的两种类型不兼容。)
6.7.2.4表示每个枚举类型(一种
enum
类型)与实现定义的
char
或有符号或无符号整数类型的选择兼容。因此,可以将指向某个
enum
的指针指定给指向一个
char
或整数类型的指针(反之亦然),但如果不了解特定的C实现,就无法知道是哪一个

6.7.3.11表示合格类型必须具有相同的限定符才能兼容。因此,
int
const int
不兼容,这会阻止
int*
被分配给
const int*

6.7.6.1 2表示要使两种指针类型兼容,它们必须是指向兼容类型的相同合格指针。例如,这告诉我们,
int*
char*
不兼容,因此,根据上述分配约束,可能无法分配
char**