演员大多没用?

我读过关于reinterpret_cast使用的各种先前的问题,并且我还阅读了C ++标准中的相关措辞。 实质上,它的缺点是指针指针reinterpret_cast操作的结果不能安全地用于除了被转换回原始指针类型以外的其他任何内容。

然而,在实践中, reinterpret_cast大多数真实世界的使用似乎基于reinterpret_cast与C风格演员相同的(错误)假设。 例如,我已经看到很多使用reinterpret_castchar*unsigned char*的代码,用于字符集转换例程。 这是完全无害的,但严格来说它不是可移植的 - 当你试图解引用unsigned char*指针时,不能保证从char*unsigned char*reinterpret_cast不会使你的程序崩溃。

根据标准,似乎reinterpret_cast的唯一其他真正用途是具有任何真正的保证,即将指针转换为整数,反之亦然。

然而,在很多情况下,我们希望(并且应该能够)在不同的指针类型之间安全地进行转换。 例如: uint16_t*指向新的C ++ 0x char16_t* ,或者指向与原始类型具有相同大小/对齐的基本数据类型的任何指针。 然而reinterpret_cast没有保证这应该起作用。

问题:如何安全地将指针转换为相同大小/对齐的基本数据类型,如char* - > unsigned char* ? 由于reinterpret_cast似乎不能保证这实际上起作用,C风格是否在这里唯一安全的选择?


当你试图解引用unsigned char *指针时,不能保证从char *到unsigned char *的reinterpret_cast不会使你的程序崩溃。

你不能以任何其他方式进行这样的演员制作,所以你必须相信你的编译器用这个完全合理的演员所做的。

由于reinterpret_cast似乎不能保证这实际上起作用,C风格是否在这里唯一安全的选择?

C风格的演员将只映射到reinterpret_cast因此它将完全相同。 在某些时候,你必须相信你的编译器。 该标准有一个限制,它只是说“不,阅读你的编译器手册”。 当谈到交叉投射指针时,这就是这样一个观点。 它可以让你读一个char用一个unsigned char左值。 不能将char*转换为可用的unsigned char*的编译器几乎不可用,并且因此而不存在。


实质上,它的缺点是指针指针reinterpret_cast操作的结果不能安全地用于除了被转换回原始指针类型以外的其他任何内容。

你是对的,标准被打破了,但N3242试图解决这个问题:

reinterpret_cast<T*>的值的定义

N3242,[expr.reinterpret.cast]:

当“T1指针”的prvalue v被转换为类型“指向cv T2的指针”时,如果T1和T2都是标准的,则结果为static_cast<cv T2*>(static_cast<cv void*>(v)) - 布局类型(3.9)和T2的对齐要求不比T1更严格。

这仍然没有定义; 为了好玩,关于static_cast的不太相关的文本:

可以将类型“指向cv1 void的指针”转换为类型为“指向cv2 T的指针”的prvalue,其中T是对象类型,并且cv2与cv1具有相同的cv限定或更高的cv限定。 空指针值被转换为目标类型的空指针值。 指向对象的类型指针的值被转换为“指向cv void的指针”并返回,可能具有不同的cv限定,应该具有其原始值。

“适当转换”

N3242,[class.mem]:

指向标准布局结构对象的指针,使用reinterpret_cast 适当转换,指向其初始成员(或者如果该成员是位域,则指向其所在的单位),反之亦然。

那是什么样的风格? “ 适当 ”? 大声笑

显然,这些人不知道如何编写规范。

C风格在这里唯一安全的选择?

它没有帮助。

标准破裂,破裂,破裂。

但是每个人都明白它的真正含义。 该标准的潜台词说:

当“指向T1的指针”类型的prvalue v被转换为类型“指向cv T2的指针”时,结果是static_cast<cv T2*>(static_cast<cv void*>(v))指向内存地址v如果T1和T2都是标准布局类型(3.9)并且T2的对齐要求不比T1更严格。

这当然不是完美的(但并不比标准的其他许多部分差),但是在2分钟内,我写了比委员会十年更好的规格。


在标准的其他地方有一些保证(参见IIRC类型表示部分,IIRC要求对应的无符号和有符号类型共享公共值的表示,仍然是IIRC,还有一些文本保证你可以读取任何字符)。 但是还要注意,有些地方甚至会减少你正在阅读的部分(其中指出事物是实现定义的和未指定的):某些形式的类型双关是未定义的行为。

链接地址: http://www.djcxy.com/p/28751.html

上一篇: cast mostly useless?

下一篇: C++ When should we prefer to use a two chained static