【问题标题】:How to understand the source code of 'nullptr' in LLVM?如何理解 LLVM 中“nullptr”的源代码?
【发布时间】:2019-02-03 21:59:24
【问题描述】:

最近,我想知道nullptr 是如何工作的。在http://www.stroustrup.com/N1488-nullptr.pdf,我找到了代码。(对不起,我没有10个声望,所以我不能在这里发布图片,你可以点击上面的链接,代码在第3页。)

代码很酷。而我又在Woboq中搜索了关键字nullptr,发现LLVM中的源代码和上面的不一样,我把它们复制在下面。

struct _LIBCPP_TEMPLATE_VIS nullptr_t
{
    void* __lx;
    struct __nat {int __for_bool_;};
    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
    template <class _Tp>
        _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR
        operator _Tp* () const {return 0;}
    template <class _Tp, class _Up>
        _LIBCPP_ALWAYS_INLINE
        operator _Tp _Up::* () const {return 0;}
    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
};
inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}
#define nullptr _VSTD::__get_nullptr_t()

最大的不同是,它定义了struct __nat和两个函数

_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}

想了很久,还是不明白LLVM为什么要这样实现。有人可以给我任何建议吗?

【问题讨论】:

  • 别抱歉。您不应该将代码作为图片发布。
  • 重要的是这个代码只在#ifdef _LIBCPP_HAS_NO_NULLPTR时使用(可能是某种兼容模式?),否则就是typedef decltype(nullptr) nullptr_t;
  • 他们在其他地方也有__natstackoverflow.com/questions/50695153/…
  • 也许这与安全布尔成语有关。

标签: c++ libc++


【解决方案1】:

'nullptr_t' 和 'nullptr' 是不同的东西。

'nullptr' 只是一个 'size_t' 值——在所有平台上都可能为 0。

'nullptr_t' 是一个类型,允许你的代码做静态 检查和区分重载,例如:

void f(int* pi)
{
   std::cout << "Pointer to integer overload\n";
}

void f(double* pd)
{
   std::cout << "Pointer to double overload\n";
}

void f(std::nullptr_t nullp)
{
   std::cout << "null pointer overload\n";
}

如果你调用'f(nullptr)',如果最后一个没有定义,会调用哪个重载?

当然你可以直接调用 'f((int*)nullptr)' 或 'f((double*)nullptr)'...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    相关资源
    最近更新 更多