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
- 在单独的翻译单元中声明的两个结构、联合或枚举类型,如果本质上声明相同,则它们是兼容的。(有趣的是,在相同的翻译单元中声明的两种类型不兼容。)
enum
类型)与实现定义的char
或有符号或无符号整数类型的选择兼容。因此,可以将指向某个enum
的指针指定给指向一个char
或整数类型的指针(反之亦然),但如果不了解特定的C实现,就无法知道是哪一个
6.7.3.11表示合格类型必须具有相同的限定符才能兼容。因此,int
与const int
不兼容,这会阻止int*
被分配给const int*
6.7.6.1 2表示要使两种指针类型兼容,它们必须是指向兼容类型的相同合格指针。例如,这告诉我们,int*
与char*
不兼容,因此,根据上述分配约束,可能无法分配char**