LLVM 的`addressof`实现为什么这么奇怪

2022-01-10 13:46:50 +08:00
 dangyuluo
template <class _Tp>
inline _LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY
_Tp*
addressof(_Tp& __x) _NOEXCEPT
{
  return reinterpret_cast<_Tp *>(
      const_cast<char *>(&reinterpret_cast<const volatile char &>(__x)));
}

一个&可以实现的功能,reinterpret_cast几次的意义是什么?谢谢

1688 次点击
所在节点    C++
3 条回复
joydee
2022-01-10 14:03:12 +08:00
1. 其实 GCC 也有这个函数:
参考: GCC4.7.1
`template<typename _Tp>
inline _Tp*
__addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
{
return reinterpret_cast<_Tp*>
(&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
}`

2. stackoverflow 上面有对这个实现的具体解释<https://stackoverflow.com/questions/16195032/implementation-of-addressof>

简短概括就是:
1) typename __Tp& 可能是 const | volatile ,所以需要 reinterpret_cast ,但是 reinterpret_cast 不能做 remove type 操作,所以需要 const_cast,至于为何选用 char 型,因为可能 char 型指针没有 alignment 显式要求。
dangyuluo
2022-01-10 14:04:59 +08:00
@joydee 哦懂了,就是说甭管有没有 CV ,先用`reinterpret_cast`添加上再说,然后再去掉。选用 char 其实是可以理解的因为是对齐最小的 type 了
qbqbqbqb
2022-01-11 12:09:42 +08:00
单用&肯定不行,因为&运算符是可以重载的。

选用 char 一是因为内置类型不可重载运算符,保证&一定是取地址的功能;二是不违反 strict aliasing rule (除 char 类型以外不允许其它的不同类型的指针指向同一段内存,否则是未定义行为)。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/827295

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX