【问题标题】:Is using reference to pointer that was casted with reinterpret_cast undefined behavior?是否使用对使用 reinterpret_cast 未定义行为强制转换的指针的引用?
【发布时间】:2021-09-10 17:02:01
【问题描述】:

下面的代码是UB吗?

int   i  = 5;
void *p  = &i;

int* &r  = reinterpret_cast<int* &>(p);
int*  p2 = r;

请注意我不会取消引用指针。

【问题讨论】:

  • 同时使用 GCC 和 Clang(主干构建),在启用额外警告的情况下构建和运行,并且 UB sanitizer sanitizer 说没关系 (see on the compiler explorer)。但它确实看起来很可疑,如果它看起来很可疑,那么我不想用十英尺长的杆子触碰这样的代码。不要这样做!
  • 您真的需要这样做吗?还是只是好奇?
  • 为什么不考虑取消引用指针?在这种情况下,我认为这不是问题。如果您竭尽全力创建指针,不妨尝试使用它。
  • @Ivan,是的,我需要。我正在为 GLib/GStreamer 制作 C++ 包装器。我的顶级基类有void* 成员。在派生类中,我需要将此成员强制转换为引用特定指针。我不能按值转换指针,因为this。我需要确切的参考。
  • 请询问您正在尝试解决的实际问题,并告诉我们您想要使用的解决方案以及您在使用该解决方案时遇到的问题。直接询问您的问题为我们提供了更多的背景信息和更好的机会来帮助您解决实际问题,而不是您在这里遇到的无背景问题。您可能想刷新the help pages,采取SO tour,阅读How to Ask,以及this question checklist。

标签: c++ undefined-behavior reinterpret-cast


【解决方案1】:

没错,就是UB。

reinterpret_cast<int* &>(p);

等价于

*reinterpret_cast<int**>(&p);

reinterpret_cast 或 void** 到 int** 是允许的,但隐式取消引用是 UB,因为数据类型 (void*) 和它被访问的类型 (int*) 不相似。

【讨论】:

    【解决方案2】:

    在这个没有尊重的绝对具体情况我认为应该没问题。我验证了指针值。当sizeof(void*) 和sizeof(int*) 不同时,情况就不同了(尽管我不知道这是否可能)。

    通过这样做,您将对众所周知的场景承担全部责任。

       int   i = 5;
       void *p = &i; //convert int* => void*
    
    
       int* &r = reinterpret_cast<int* &>(p); //convert void* which was int* to int*&
       int*  p2 = r; //**copy** address stays same
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-17
      相关资源
      最近更新 更多