如果我可以保证使用正确的类型来分配内存,使用 reinterpret_cast 是否安全?

Is it safe to use a reinterpret_cast if I can guarantee the correct type was used to allocate the memory?

我正在尝试使我的 C++ 代码跨平台。在 Windows 上,我使用 Windows.h 头文件,在 macOS 和 Linux 上,我使用 unistd.h 头文件。

如果 OS 是采用 char* 类型的 windows,我将调用一个函数。 mac 和 linux 的等效调用采用 char**。我目前有一个采用 void* 类型的函数,因此我可以为这两种情况使用 1 个函数。然后我检查操作系统和 reinterpret_cast 到正确的类型。

void DoSomething(void* thing) {

  #if defined(__APPLE__) || defined(__linux__)

  // Init thing as char**
  thing = new char*[...];
    thing[0] = new char[...];
    .
    .
    .

  UnixFunction(reinterpret_cast<char**>(thing));

  #elif defined(_WIN32)

  // Init thing as char*
  thing = new char[...];
  WindowsFunction(reinterpret_cast<char*>(thing));
  #endif
}

int main() {

  void* thing;
  DoSomething(thing);

  return 0;

}

不管我是否应该这样做,这安全还是未定义的行为?

听起来你问的是安全的。但是,您的代码看起来有点不对劲:

void DoSomething(void* thing) {
    thing = new char*[...];

这将使调用者无法访问分配的内存,因为 thing 是调用者传入的地址,但随后您立即覆盖了该地址,因此您无法将调用者给了你,and/or调用者无法知道你分配了什么内存。

例如,您可以采用 (void*& thing) 以便您对指针所做的更改对调用者可见。或者只是 return 来自函数的指针。

如果您修复了该设计错误,reinterpret_cast 本身就不会成为问题。你甚至可以将指针指向 uintptr_tintptr_t,然后使用 reinterpret_cast 再次返回,如果你想要一种方法来传递地址而无需知道类型,直到你再次使用它们。