gpt4 book ai didi

c++ - reinterpret_cast(p) 或 static_cast((void*)p)) 用于字节指针差异,哪个更好?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:31:03 24 4
gpt4 key购买 nike

在提取用于指针运算的原始字节指针时,以下三种类型转换之间有什么区别吗? (假设 char 为 1 个字节的平台。)

  1. static_cast<char*>((void*)ptr))
  2. reinterpret_cast<char*>(ptr)
  3. (更新)或:static_cast<char*>(static_cast<void*>(ptr))

我应该选择哪个?

更详细...

给定一个类中两个成员对象的指针,我想计算一个到另一个的偏移量,这样我就可以在给定偏移量的情况下重建一个成员的地址和另一个成员的地址。

// assumed data layout:
struct C {
// ...
A a;
// ...
B b;
}

我目前使用的代码是这样的:

void approach1( A *pa, B *pb )
{
// compute offset:
std::ptrdiff_t offset = static_cast<char*>((void*)pa) - static_cast<char*>((void*)pb);
// then in some other function...
// given offset and ptr to b, compute ptr to a:
A *a = static_cast<A*>( (void*)(static_cast<char*>((void*)pb) + offset) );
}

main()
{
C c;
approach1(&c.a, &c.b);
}

我想知道以下是更好(还是更差):

void approach2( A *pa, B *pb )
{
std::ptrdiff_t offset = reinterpret_cast<char*>(pa) - reinterpret_cast<char*>(pb);
// ...
A *a = reinterpret_cast<A*>( reinterpret_cast<char*>(pb) + offset );
}

这两种方法是否完全等同?它们是否同样便携?

我的印象是approach1()更便携,因为“ static_cast ing a pointer to and from void* preserves the address ”,而 reinterpret_cast<>保证更少(请参阅链接中接受的答案)。

我想知道最简洁的方法是什么。

更新:目的说明

很多人问计算这些偏移量的目的是什么。目的是构造一个实例偏移量的元类表。这被运行时反射机制用于自动 GUI 构建和持久化(偏移量未序列化,仅用于遍历结构)。该代码已投入生产超过 15 年。出于这个问题的目的,我只想知道计算指针偏移量的最便携方法。我无意对元类系统的工作方式进行重大更改。此外,我通常也对执行此操作的最佳方法感兴趣,因为我还有其他用途(例如共享内存代码的差异指针)。

注意:我不能使用 offsetof()因为在我的实际代码中我只有指向实例的指针 ab , 我不一定有包含对象的类型 c或其他要使用的静态信息 offsetof() .我只能假设ab是同一对象的成员。

最佳答案

这两个将导致相同的结果,所以差异主要是语义上的,reinterpret_cast 具有您想要的操作的确切含义,再加上只需要一次转换而不是两次 (代码中的转换越少越好)。

reinterpret_cast

5.2.10/7: An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of object pointer type is converted to the object pointer type “pointer to cv T”, the result is static_cast< cv T* >(static_cast< cv void* >(v)).

因此,除非在中年平台上出现奇特的随机低级不同行为,否则您绝对应该选择:

reinterpret_cast<char*>(ptr);

一般。

就是说,你为什么不使用 uintptr_t在你的情况下?它更合适,你不需要指针:

void approach3( A *pa, B *pb )
{
std::ptrdiff_t offset = reinterpret_cast<std::uintptr_t>(pa) - reinterpret_cast<std::uintptr_t>(pb);
// ...
A *a = reinterpret_cast<A*>( reinterpret_cast<std::uintptr_t>(pb) + offset );
}

有关其他信息,请参阅:

http://en.cppreference.com/w/cpp/language/reinterpret_cast

关于c++ - reinterpret_cast<char*>(p) 或 static_cast<char*>((void*)p)) 用于字节指针差异,哪个更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25638770/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com