Как понять исходный код 'nullptr' в LLVM? - PullRequest
0 голосов
/ 29 августа 2018

В последнее время я хочу знать, как работает nullptr. В http://www.stroustrup.com/N1488-nullptr.pdf я нашел код. (Извините, у меня нет 10 репутаций, поэтому я не могу размещать изображения здесь, вы можете перейти по ссылке выше, код на странице 3.)

Код классный. И я снова искал ключевое слово nullptr в Woboq , я обнаружил, что исходный код в 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 реализовал это так. Может кто-нибудь дать мне какой-нибудь совет?

1 Ответ

0 голосов
/ 06 декабря 2018

'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)' ...

...