【问题标题】:Force reinterpret_cast to return nullptr强制 reinterpret_cast 返回 nullptr
【发布时间】:2021-05-22 12:13:45
【问题描述】:

我正在为一个将内存地址作为unsigned long 接收的函数创建单元测试

在函数内部,这个地址是reinterpret_casted 到你的类之一的指针中。

void my function(Address inputAdress ) // Address comes from: typedef unsigned long Address;
{
  ClsMyClassThread* ptr = reinterpret_cast<ClsMyClassThread*>(inputAdress);

  if(ptr == nullptr)
  {
    // Do something 
  }
}

此函数运行良好,但在为其创建 UnitTest 时,我不知道如何将 ptr 强制为 nullptr(我想测试全覆盖)。这什么时候会发生?这可能吗?

谢谢!

【问题讨论】:

  • 整数值 0 通常转换为 nullptr
  • nullptr转换为参数类型,传递给函数

标签: c++ unit-testing casting reinterpret-cast


【解决方案1】:

来自reinterpret_cast conversion 第 3 点(强调我的):

  1. 任何整数或枚举类型的值都可以转换为指针类型。 转换为足够大小的整数并返回相同指针类型的指针保证具有其原始值,否则无法安全地取消引用生成的指针(相反方向的往返转换是不保证;同一个指针可能有多个整数表示)不保证空指针常量NULL 或整数零产生目标类型的空指针值static_cast 或隐式转换应用于此目的。

因此,这样做的正确方法(假设 sizeof(Address) 足够大)是:

myfunction(reinterpret_cast<Address>(static_cast<ClsMyClassThread*>(nullptr)));

而以下一些人的建议保证有效:

myfunction(0);

【讨论】:

  • @dyp 抱歉,现在轮到我困惑了,因为我不明白你在说什么。
  • 那么如果你这样做reinterpret_cast&lt;T*&gt;(reinterpret_cast&lt;uintptr_t&gt;(nullptr)),结果是什么?和reinterpret_cast&lt;T*&gt;(reinterpret_cast&lt;uintptr_t&gt;((void*)0))一样。
  • @dyp 请注意,“转换与将(void*)0 转换为整数类型具有相同的含义和有效性。” 声称转换将导致0。将(void*) 0 视为可能具有任何未指定位模式的“神奇空指针对象”,因为标准是这样看待它的。
  • 我认为打破它的是要求“将指针转换为足够大小的整数 [...] 并返回到 相同的指针类型”。 void* != ClsMyClassThread*
  • @Eljay 实现定义。 [expr.reinterpret.cast]/5
【解决方案2】:

这些很可能会起作用:

my_function(NULL);
my_function(0);
Address a = 0;
my_function(a);

虽然技术上绝对正确,但您需要:

my_function(reinterpret_cast<Address>(static_cast<ClsMyClassThread*>(nullptr)));

(标准保证从零到指针类型的转换是空指针值,仅当涉及的零是直接文字表达式时,而不是变量,例如 inputAdress,它恰好具有零值。因此,它使用保证两个逆 reinterpret_cast 表达式。)

【讨论】:

    猜你喜欢
    • 2021-07-21
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多