在特定偏移量和类型处reinterpret_cast原始结构的安全方法?
return *reinterpret_cast<UInt32*>((reinterpret_cast<char*>(this) + 2));
Struct 是 pragma 打包的 1 并包含一堆 uint、char、short 字段...
既然它是 UInt32,是否应该首先将它reinterpret_cast 为 unsigned char* 或者它甚至重要?
另外,速度在这里至关重要,我相信与 static_cast 相比,reinterpret_cast 是最快的转换。
编辑:该结构实际上由两个单字节字段组成,后跟大约 16 个其他结构的联合,其中 15 个将 UInt32 作为其第一个字段。我快速检查了一下,确定它不是没有的,然后对 2 字节偏移量进行reinterpret_cast。
return *reinterpret_cast<UInt32*>((reinterpret_cast<char*>(this) + 2));
Struct is pragma packed 1 and contains a bunch of uint, char, short fields...
Since it's UInt32, should it first be reinterpret_cast to unsigned char* instead or does it even matter?
Also, speed is critical here and I believe reinterpret_cast is the fastest of the casts as opposed to static_cast.
EDIT: The struct is actually composed of two single-byte fields followed by a union of about 16 other structs 15 of which have the UInt32 as its first field. I do a quick check that it's not the one without and then do the reinterpret_cast to the 2 byte offset.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
直接访问会员不行吗?这是未定义的行为,并且在强制字对齐的系统上根本不起作用(考虑到您正在这样做,这可能不是问题,但需要提及)。
reinterpret_cast
不会比static_cast
快,因为它们只是告诉编译器如何在编译时使用内存。然而dynamic_cast
会更慢。没有合法的方法可以将
struct + offset
视为非char
类型。Can't you just access the member directly? This is undefined behavior and won't work at all on systems that enforce word alignment (which is probably not a problem given you're doing it but needs to be mentioned).
reinterpret_cast
wouldn't be any faster thanstatic_cast
because they just tell the compiler how to use memory at compile time. Howeverdynamic_cast
would be slower.There's no legal way to just treat your
struct + offset
as a non-char
type.reinterpret_cast
和static_cast
应具有相同的运行时间 - 接近于零,除非需要执行数值转换。您应该选择要使用的演员表,而不是基于“速度”,而是基于正确性。如果您正在谈论dynamic_cast
,您可能会有争论的理由,但是reinterpret_cast
和static_cast
通常都会导致(最坏的情况)寄存器副本(例如从整数寄存器到浮点寄存器)。 (假设没有用户定义的转换运算符进入图片,那么它是一个函数调用及其所有伴随的东西)没有安全的方法来完成你正在做的事情。这违反了严格别名规则。如果您想做这样的事情,您的
struct
需要采用某种形式的union
,您可以通过 union 访问UInt32
。最后,如前所述,该示例在任何存在对齐问题的平台上都会失败。这意味着您可以在 x86 上正常工作,但在 x64 上就不行了。
reinterpret_cast
andstatic_cast
should have the same runtime -- next to zero unless numerical conversion needs to be performed. You should choose the cast to use not based on "speed", but based on correctness. If you were talking aboutdynamic_cast
you might have a cause for argument, but bothreinterpret_cast
andstatic_cast
usually lead to (at worst) a register copy (E.g. from an integer register into a floating point register). (Assuming no user defined conversion operators get into the picture, then it's a function call with all it's attendant stuff)There is no safe way to do what you're doing. That breaks the strict aliasing rule. If you wanted to do something like this your
struct
would need to be in some form ofunion
where you access theUInt32
through the union.Finally, as already mentioned, that example will fail on any platform with alignment issues. That means you'll be fine on x86, but will not be fine on x64, for example.
您忘记提及,您使用的是指向结构的指针,而不是结构本身,无论如何,我发现对于结构的特定字段没有必要使用指针算术。使用指针算术的编译器和生成的代码不会更快,并且会使您的代码不必要地更加复杂:
干杯。
UPDATE1:在示例中添加了“union”。
You forgot to mention, that you are using a pointer to an struct, not a struct by itself, in any case, I find unnecesary to use pointer arithmetic, for a particular field of a struct. The compiler and generated code, won't be any faster for using pointer arithmetic, and would make your code more comples, unnecesarily:
Cheers.
UPDATE1: Added "union" to example.
既然你说结构体包含整数和短裤,我将冒险并假设这个联合是 POD 来回答。如果是这样,那么您将受益于 9.5/1:
看起来像这样:
那么你可以这样做:
如果联合的成员不是 POD,那么你的
reinterpret_cast
无论如何都会被破坏,因为不再有任何保证结构体的第一个数据成员位于距结构体开头的偏移量 0 处。Since you say that the struct contains ints and shorts, I'm going to go out on a limb and answer on the assumption that this union is POD. If so then you benefit from 9.5/1:
So, assuming your structure looks like this:
Then you can do this:
If the members of the union aren't POD, then your
reinterpret_cast
is broken anyway, since there is no longer any guarantee that the first data member of the struct is located at offset 0 from the start of the struct.