【发布时间】:2021-02-01 22:27:56
【问题描述】:
考虑以下 sn-p:
char x[100];
double *p = &x;
正如预期的那样,这会产生以下警告:
f.c:3:15: warning: initialization of ‘double *’ from incompatible pointer type ‘char (*)[100]’
[-Wincompatible-pointer-types]
3 | double *p = &x;
| ^
这很容易解决,只需更改为
double *p = (double*)&x;
我的问题是,选角真的有什么作用吗?如果没有演员表,代码会无效吗?或者它只是一种让编译器安静的方法?什么时候需要铸造?
我知道你可以像这样使用 sn-ps 产生一些效果:
int x = 666;
int y = (char)x;
但是这和这个不一样吗?
int x = 666;
char c = x;
int y = c;
如果是相同的,那么强制转换会做一些事情,但它不是必要的。对吧?
请帮助我理解这一点。
【问题讨论】:
-
在该分配违反严格的别名规则之后取消引用
p,无论有无强制转换。所以演员表使警告静音,但留下未定义的行为。 -
转换可能会有所作为;在某些 C 实现中,
double *的表示可能与char *的表示不同。演员做某事;如果赋值的左操作数和右操作数的类型不“匹配”(满足某些规则)但不用于强制转换,则 C 标准要求进行诊断。 -
指针类型之间的转换通常在现代系统中大多是空操作。但是,如果
char *与其他数据类型未对齐,如果您尝试通过未对齐的指针访问double,某些机器可能会产生“总线错误”。其他机器可能会产生相当大的开销(系统陷阱和处理错位的代码)。 -
整数类型之间的隐式转换是有规则的。指针的规则是不允许不兼容的指针赋值。
-
@Peter-ReinstateMonica:关于“C ISO 草案 1256, 6.3.2.3/7,使用独立于其类型的对象指针转换提供往返保证”:不,它没有。仅当满足对齐要求时,才存在往返保证。这意味着从更宽松对齐类型到更严格对齐类型的转换可能会丢失信息。