【问题标题】:What is the idiom here when static_cast is used on null pointer?在空指针上使用 static_cast 时,这里的成语是什么?
【发布时间】:2020-10-16 17:34:44
【问题描述】:

静态分析将此代码标记为 nullPointerArithmetic:

static_cast<BYTE*>(NULL) + p_row_fields->offsets.back(), // field offset

其中 NULL 定义为 #define NULL 0 而offsets通过typedef解析为std::vector&lt;int&gt;

有问题的行作为 BYTE* 参数传递给方法调用。

我的问题是 - 这个成语的目的是什么?

所展示的和不那么折衷的直接演员有什么区别:

static_cast<BYTE*>(p_row_fields->offsets.back())

【问题讨论】:

  • 没有看到相邻的代码,没有真正的方法来解释作者的意图。不能到达边界的指针的 IIRC 算术要么是未定义的行为,要么是未指定的,因此这种空指针算术无论如何都是无效的。旁注:您不能将static_castint 指向指针类型——这需要reinterpret_cast。您只能将 static_cast nullptr 或文字 0 指向指针。
  • 原始表达式(将整数添加到 nullptr)是未定义行为,除非整数为 0。
  • @1201ProgramAlarm 好的,我误解了;所以这不仅仅是误报,而是真正未定义 - 你能提供更具体的参考吗?
  • 这可能是offsetof 的用户编写实现。如果是这样,这个问题说明了为什么offsetof 在标准库中。

标签: c++ null pointer-arithmetic static-cast


【解决方案1】:

空指针常量转换为任何指针类型,产生该指针类型的空指针值。因此,static_cast&lt;BYTE*&gt;(NULL) 产生一个 BYTE* 类型的空指针。这种转换也是隐式的。

严格来说,指针运算在 null 上的行为是标准未定义的,因为(或假设)在 null 地址处没有数组。

假设编译器允许这种行为在实践中可能是什么行为,人们可能会期望它的行为与以下内容相同:

reinterpret_cast<Byte*>(
    static_cast<std::intptr_t>(
        p_row_fields->offsets.back()
    )
)

虽然这不是 UB,但在技术上仍然没有标准保证生成的地址是预期的。

所展示的和不那么折衷的直接演员有什么区别:

static_cast<BYTE*>(p_row_fields->offsets.back())

是的,有区别。在整数表达式中,只有值为 0 的编译时常量纯右值可转换为指针类型。 0 以外的值和 p_row_fields-&gt;offsets.back() 等左值不能静态转换为指针。

因此,引用的演员表格式错误。

【讨论】:

  • 啊 - 我可以验证编译器不接受这个 ('static_cast': cannot convert from '_Ty' to 'BYTE *')。所以看来原作者不想在这里使用reinterpret_cast(这似乎是“正确的”成语)
  • @giles 或者原作者可能不知道在这里使用reinterpret_cast,而是四处寻找似乎有效的东西。 ;)
  • @JaMiT 这是一种理论。另一种可能性是他们知道 reinterpret_cast,但读到结果指针值未指定,并认为他们找到了“更好”的方法。
猜你喜欢
  • 1970-01-01
  • 2014-12-04
  • 2022-06-14
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 2017-11-30
  • 2012-02-26
相关资源
最近更新 更多