[英]How does this reinterpret_cast work? (Porting C++ to Java)
[英]C++ how does cast with reference work?
谁能解释下面的代码中发生了什么?
char cd[1024];
unsigned short int & messageSize =reinterpret_cast<unsigned short int&>(*cd);
是否通过引用将cd的前2个字符转换为16位int? 当我删除“&”时,编译器抱怨无法从char强制转换为unsigned short int。
unsigned short int messageSize =reinterpret_cast<unsigned short int>(*cd);
reinterpret_cast
的“直观”含义是“采用位序列并将其视为该位序列具有不同的类型”。 对于char
和unsigned short
类型,这是不可能的,因为它们的宽度不同。
对于第一种情况,直觉是: reinterpret_cast
将左值引用当作是指向它引用的类型的指针一样对待(并将提及的转换应用于该指针)。
该标准正式表示:
4.2数组到指针的转换[conv.array]
- 可以将“ NT数组”或“ T的未知边界数组”类型的左值或右值转换为“指向T的指针”类型的prvalue。 结果是一个指向数组第一个元素的指针。
和:
5.3.1一元运算符[expr.unary.op]
- 一元
*
运算符执行间接操作:应用该表达式的表达式应为指向对象类型的指针或为函数类型的指针,并且结果为指向表达式所指向的对象或函数的左值。 如果表达式的类型为“ T的指针”,则结果的类型为“ T”。
因此,在取消引用*cd
我们将得到一个char
类型的左值(就像您写了cd[0]
)。
5.2.10重新解释演员表[expr.reinterpret.cast]
- 如果可以使用
reinterpret_cast
将类型“指向T1的指针”显式转换为类型“指向T2的指针”,则可以将类型T1的glvalue表达式强制转换为“对T2的引用”类型。 结果指向与源glvalue相同的对象,但是具有指定的类型。 [注:即,对于左值,基准铸造reinterpret_cast<T&>(x)
具有作为转换相同的效果*reinterpret_cast<T*>(&x)
与内置&
和*
运营商(以及类似地用于reinterpret_cast<T&&>(x)
)。 —注释[end note]不会创建临时文件,不会创建副本,也不会调用构造函数(12.1)或转换函数(12.3)。
那意味着,你有类似
*reinterpret_cast<unsigned short *>(&cd[0])
但是,可能比上述所有内容更重要的是:
3.10左值和右值[basic.lval]
如果程序尝试通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:
- 对象的动态类型,
- 对象动态类型的cv限定版本,
- ...
- 字符或无符号字符类型。
也就是说,将“对char的引用”绑定到类型为“ unsigned short”的对象是可以的。 但是反之亦然(例如,在您的示例中)是不可行的,因为访问此类引用将调用未定义的行为。
具有引用的强制转换与没有引用的相同强制转换的不同之处在于,没有引用的强制转换会创建一个新的临时对象,而具有引用的强制转换会更改现有对象的类型。 在许多情况下,例如在您的情况下,这很重要,因为您将结果分配给非常量引用。 非const引用不能使用临时对象初始化。
附带说明一下,您知道您在这里所做的事违反了类型别名规则,并且会产生不合法的行为吗?
unsigned short int & messageSize
表示messageSize
是unsigned short int
类型的变量,并且将存储该变量的存储区应作为初始化程序。
初始化程序=reinterpret_cast<unsigned short int&>(*cd)
说:在cd
指向的位置获取内存,并假装它包含unsigned short int
。
结果是,如果您尝试读写messageSize
,那么您将尝试在包含其他内容的内存位置中读写一个unsigned short int
。 这会导致不确定的行为。
在某些情况下,可以假装内存位置包含实际上不包含的对象; 这不是其中的一个。
如果您的编译器没有执行别名优化,那么它看起来好像您的代码现在“可以正常工作”。 但是,代码已损坏。
reinterpret_cast<unsigned short int&>(*cd);
类似于
*reinterpret_cast<unsigned short int*>(cd);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.