什么时候我们更喜欢在reinterpret_cast上使用两个链式的static_cast

时间:2021-12-11 06:01:38

First of all, this is not a duplicate of Why do we have reinterpret_cast in C++ when two chained static_cast can do it's job?.

首先,这不是为什么我们在c++中有reinterpret_cast,而两个链式的static_cast可以完成它的工作?

I know situations where we cannot use even two chained static_cast to achieve that, what reinterpret_cast does. But is there any situation where I should prefer a two chained static_cast over a simple and more readable reinterpret_cast?

我知道在某些情况下,我们甚至不能使用两个链式的static_cast来实现它,reinterpret_cast就是这样做的。但是,在任何情况下,我应该更喜欢两个链式的static_cast而不是一个简单的、可读性更好的reinterpret_cast?

6 个解决方案

#1


8  

reinterpret_cast should be a huge flashing symbol that says THIS LOOKS CRAZY BUT I KNOW WHAT I'M DOING. Don't use it just out of laziness.

reinterpret_cast应该是一个巨大的闪烁符号,它表示这个看起来很疯狂,但是我知道我在做什么。不要因为懒惰而使用它。

reinterpret_cast means "treat these bits as ..." Chained static casts are not the same because they may modify their targets according to the inheritence lattice.

reexplain t_cast的意思是“把这些位当作…”链式的静态类型转换不一样,因为它们可以根据继承格修改目标。

struct A {
    int x;
};

struct B {
    int y;
};

struct C : A, B {
    int z;
};

C c;
A * a = &c;

int main () {
    assert (reinterpret_cast <B *> (a) != static_cast <B *> (static_cast <C *> (a)));
}

If you are not 100% sure that a points to a b, use dynamic_cast which will search for the above solution (albeit with a runtime cost). Bear in mind that this may return NULL or throw on failure.

如果您不能100%确定a指向b,请使用dynamic_cast,它将搜索上述解决方案(尽管有运行时成本)。记住,这可能返回NULL或抛出失败。

I'm trying to think of times when I've actually used reinterpret_cast, there are really only two:

我试着去想当我使用reinterpret_cast时,实际上只有两个:

  • when a function is zipping/encrypting an arbitrary buffer and I want to use a const char * to traverse it
  • 当一个函数在压缩/加密一个任意的缓冲区时,我想使用一个const char *来遍历它。
  • if(*reinterpret_cast<uint32_t*>(array_of_4_bytes_A) < *reinterpret_cast<uint32_t*>(array_of_4_bytes_B) or somesuch. Lines like this invite scrutiny and demand comments.
  • 如果(* reinterpretation t_cast (array_of_4_bytes_A) < * reinterpretation t_cast (array_of_4_bytes_B)或somesuch)。像这样的句子会引起审查和要求评论。 *> *>

Otherwise if you have a A* which is really a B* then you probably want a union.

否则,如果你有一个a *,实际上是B*,那么你可能想要一个联合。

#2


5  

I for one would rather see reinterpret_cast <TargetType> (pointer_of_some_other_type) than static_cast <TargetType> (static_cast <void*> (pointer_of_some_other_type)) or static_cast <TargetType> ((void*) (pointer_of_some_other_type)) any time. That chain of casts going through void* is just a sneaky, underhanded way to avoid using the dreaded reinterpret_cast.

我宁愿看到reinterpret_cast (pointer_of_some_other_type),也不愿看到static_cast (static_cast (pointer_some_other_type))或static_cast (void*) (pointer_of_other_time)。通过void*进行的转换是一种狡猾的、卑鄙的方法,以避免使用可怕的re解释t_cast。 *>

Many projects ban the use of reinterpret_cast unless a waiver is granted; the person who wrote the code needs to justify the use of the cast. IMO, a chain of static casts is worse (much worse!) than is reinterpret_cast. The chain has the same effects, the same problems as does a reinterpret_cast, but the chain does not have the benefit of being easy to find with a grep.

许多项目禁止使用reinterpretation t_cast,除非获得豁免;编写代码的人需要证明强制转换的使用是合理的。在我看来,静态类型转换链比reinterpret_cast更糟糕(更糟糕!)。该链具有相同的效果,同样的问题与重新解释的转换相同,但是该链不具有使用grep查找方便的优点。

Addendum
Look at it this way. Case 1, you use reinterpret_cast, you go through all the project hoops to justify its use, the project manager grants a waiver. Months later, an error is traced to your use of dynamic_cast. You have a get out of jail free card. It is the project manager's ass that is on the line for giving you that card.

附录这样看。案例1,您使用reinterpretation t_cast,您遍历所有的项目约束来证明它的使用,项目经理授予弃权。几个月后,一个错误被跟踪到您使用dynamic_cast。你有一张出狱免费卡。是项目经理的屁股给了你那张卡。

Case 2, you use the sneaky, underhanded chain of static casts and the code sneaks through peer review unscathed. Months later, an error is traced to your use of despicable technique. Your project manager might be in a bit of trouble for not catching this nastiness, but it is your ass that is on the line. You do not have that get out of jail free card. You do not pass Go. You go directly to the unemployment line.

案例2,您使用了偷偷摸摸的、不为人知的静态强制类型转换链,代码可以毫发无损地通过同行评审。几个月后,一个错误被追溯到你使用卑鄙的技术。你的项目经理可能会因为没有发现这个问题而惹上麻烦,但这是你的麻烦。你没有那张出狱免费卡。你别错过了。你直接去失业热线。

#3


2  

Always use reinterpret cast as a last resort - it doesn't do any checking! - so if you can chain two, three or ten statements together that do some kind of validation on the operation then you've gained something worthwhile.

总是使用重新解释的石膏作为最后的手段-它不做任何检查!-如果你能将2、3或10个语句串在一起,对操作进行某种验证,那么你就获得了一些有价值的东西。

#4


2  

Since, the listing of the scenarios can go very long, I am putting in simple words:

因为这些场景的列表可能会很长,所以我用简单的话来说:

If chained static_cast<>s don't give compile-error, you should avoid reinterpret_cast<>.

如果链式的static_cast<>s没有给出编译错误,那么应该避免reinterpretation t_cast<>。

#5


1  

You should not use reinterpret_cast in cases where cross-cast pointers - instead use implicit conversion to void*, then static_cast.

在交叉转换指针的情况下,不应该使用reinterpret_cast—而应该使用隐式转换到void*,然后是static_cast。

#6


0  

Because in theory, they could do something different (although it's hard to imagine such a case). More importantly, they send different signals to the reader, and tell a different story to the compiler (which could affect optimization). Logically, I'd say use chained static_cast through void* for cases to/from a character type (e.g. dumping an image of the raw memory), and other cases which are well defined and portable, and reinterpret_cast when you're doing real low level, hardware dependent work: extracting the exponent field of a float by casting its address to an unsigned int*, and bit masking, for example.

因为从理论上讲,他们可以做一些不同的事情(尽管很难想象这种情况)。更重要的是,它们向读者发送不同的信号,并向编译器讲述不同的故事(这可能会影响优化)。从逻辑上讲,我认为使用链接通过void * static_cast案件/从一个字符类型(例如,倾倒一个图像的原始内存),和其他情况下定义良好和便携式,reinterpret_cast当你做真正的低水平,硬件相关的工作:提取一个浮点数的指数领域通过铸造其地址到一个unsigned int *,和一些屏蔽,例如。

#1


8  

reinterpret_cast should be a huge flashing symbol that says THIS LOOKS CRAZY BUT I KNOW WHAT I'M DOING. Don't use it just out of laziness.

reinterpret_cast应该是一个巨大的闪烁符号,它表示这个看起来很疯狂,但是我知道我在做什么。不要因为懒惰而使用它。

reinterpret_cast means "treat these bits as ..." Chained static casts are not the same because they may modify their targets according to the inheritence lattice.

reexplain t_cast的意思是“把这些位当作…”链式的静态类型转换不一样,因为它们可以根据继承格修改目标。

struct A {
    int x;
};

struct B {
    int y;
};

struct C : A, B {
    int z;
};

C c;
A * a = &c;

int main () {
    assert (reinterpret_cast <B *> (a) != static_cast <B *> (static_cast <C *> (a)));
}

If you are not 100% sure that a points to a b, use dynamic_cast which will search for the above solution (albeit with a runtime cost). Bear in mind that this may return NULL or throw on failure.

如果您不能100%确定a指向b,请使用dynamic_cast,它将搜索上述解决方案(尽管有运行时成本)。记住,这可能返回NULL或抛出失败。

I'm trying to think of times when I've actually used reinterpret_cast, there are really only two:

我试着去想当我使用reinterpret_cast时,实际上只有两个:

  • when a function is zipping/encrypting an arbitrary buffer and I want to use a const char * to traverse it
  • 当一个函数在压缩/加密一个任意的缓冲区时,我想使用一个const char *来遍历它。
  • if(*reinterpret_cast<uint32_t*>(array_of_4_bytes_A) < *reinterpret_cast<uint32_t*>(array_of_4_bytes_B) or somesuch. Lines like this invite scrutiny and demand comments.
  • 如果(* reinterpretation t_cast (array_of_4_bytes_A) < * reinterpretation t_cast (array_of_4_bytes_B)或somesuch)。像这样的句子会引起审查和要求评论。 *> *>

Otherwise if you have a A* which is really a B* then you probably want a union.

否则,如果你有一个a *,实际上是B*,那么你可能想要一个联合。

#2


5  

I for one would rather see reinterpret_cast <TargetType> (pointer_of_some_other_type) than static_cast <TargetType> (static_cast <void*> (pointer_of_some_other_type)) or static_cast <TargetType> ((void*) (pointer_of_some_other_type)) any time. That chain of casts going through void* is just a sneaky, underhanded way to avoid using the dreaded reinterpret_cast.

我宁愿看到reinterpret_cast (pointer_of_some_other_type),也不愿看到static_cast (static_cast (pointer_some_other_type))或static_cast (void*) (pointer_of_other_time)。通过void*进行的转换是一种狡猾的、卑鄙的方法,以避免使用可怕的re解释t_cast。 *>

Many projects ban the use of reinterpret_cast unless a waiver is granted; the person who wrote the code needs to justify the use of the cast. IMO, a chain of static casts is worse (much worse!) than is reinterpret_cast. The chain has the same effects, the same problems as does a reinterpret_cast, but the chain does not have the benefit of being easy to find with a grep.

许多项目禁止使用reinterpretation t_cast,除非获得豁免;编写代码的人需要证明强制转换的使用是合理的。在我看来,静态类型转换链比reinterpret_cast更糟糕(更糟糕!)。该链具有相同的效果,同样的问题与重新解释的转换相同,但是该链不具有使用grep查找方便的优点。

Addendum
Look at it this way. Case 1, you use reinterpret_cast, you go through all the project hoops to justify its use, the project manager grants a waiver. Months later, an error is traced to your use of dynamic_cast. You have a get out of jail free card. It is the project manager's ass that is on the line for giving you that card.

附录这样看。案例1,您使用reinterpretation t_cast,您遍历所有的项目约束来证明它的使用,项目经理授予弃权。几个月后,一个错误被跟踪到您使用dynamic_cast。你有一张出狱免费卡。是项目经理的屁股给了你那张卡。

Case 2, you use the sneaky, underhanded chain of static casts and the code sneaks through peer review unscathed. Months later, an error is traced to your use of despicable technique. Your project manager might be in a bit of trouble for not catching this nastiness, but it is your ass that is on the line. You do not have that get out of jail free card. You do not pass Go. You go directly to the unemployment line.

案例2,您使用了偷偷摸摸的、不为人知的静态强制类型转换链,代码可以毫发无损地通过同行评审。几个月后,一个错误被追溯到你使用卑鄙的技术。你的项目经理可能会因为没有发现这个问题而惹上麻烦,但这是你的麻烦。你没有那张出狱免费卡。你别错过了。你直接去失业热线。

#3


2  

Always use reinterpret cast as a last resort - it doesn't do any checking! - so if you can chain two, three or ten statements together that do some kind of validation on the operation then you've gained something worthwhile.

总是使用重新解释的石膏作为最后的手段-它不做任何检查!-如果你能将2、3或10个语句串在一起,对操作进行某种验证,那么你就获得了一些有价值的东西。

#4


2  

Since, the listing of the scenarios can go very long, I am putting in simple words:

因为这些场景的列表可能会很长,所以我用简单的话来说:

If chained static_cast<>s don't give compile-error, you should avoid reinterpret_cast<>.

如果链式的static_cast<>s没有给出编译错误,那么应该避免reinterpretation t_cast<>。

#5


1  

You should not use reinterpret_cast in cases where cross-cast pointers - instead use implicit conversion to void*, then static_cast.

在交叉转换指针的情况下,不应该使用reinterpret_cast—而应该使用隐式转换到void*,然后是static_cast。

#6


0  

Because in theory, they could do something different (although it's hard to imagine such a case). More importantly, they send different signals to the reader, and tell a different story to the compiler (which could affect optimization). Logically, I'd say use chained static_cast through void* for cases to/from a character type (e.g. dumping an image of the raw memory), and other cases which are well defined and portable, and reinterpret_cast when you're doing real low level, hardware dependent work: extracting the exponent field of a float by casting its address to an unsigned int*, and bit masking, for example.

因为从理论上讲,他们可以做一些不同的事情(尽管很难想象这种情况)。更重要的是,它们向读者发送不同的信号,并向编译器讲述不同的故事(这可能会影响优化)。从逻辑上讲,我认为使用链接通过void * static_cast案件/从一个字符类型(例如,倾倒一个图像的原始内存),和其他情况下定义良好和便携式,reinterpret_cast当你做真正的低水平,硬件相关的工作:提取一个浮点数的指数领域通过铸造其地址到一个unsigned int *,和一些屏蔽,例如。