Nano Hash - криптовалюты, майнинг, программирование

Вычитание нулевого указателя из обычного указателя?

Я наткнулся на эту функцию:

    int foo(int *p)
    {
      return p - (int*)0;
    }

Может кто-нибудь объяснить, что это делает? Кажется, он возвращает целое число. Какая логика стоит за этим вычитанием нулевого указателя? Также был комментарий, что это чистая и реентерабельная функция.

22.05.2013

  • Это выглядит довольно случайным. Это даже не вычитание значения, а просто перемещение смещения по указателю на int 0. 22.05.2013
  • Вот объяснение stackoverflow.com/questions/8128168/ 22.05.2013
  • Он возвращает значение int указателя. Конечно, если указатель больше, чем int, произойдет усечение. 22.05.2013
  • (int*)0 выглядел так в исходном коде или это был пользовательский макрос? Если бы это был макрос типа ROM_BASE, вышеизложенное могло бы иметь гораздо больше смысла, чем если бы это был буквальный ноль. 18.10.2018

Ответы:


1

Он имеет неопределенное поведение, поскольку арифметика указателя определена только внутри массива.

На практике на машине, которая представляет указатели числовым адресом, с достаточно большими целыми числами и нулевым указателем, представленным нулевым адресом, он преобразует адрес байта в адрес слова. То есть он дает количество кусков памяти размером int между адресом нулевого указателя и адресом p.

Также был комментарий, что это чистая и реентерабельная функция.

«Чистый» означает, что он не имеет побочных эффектов, а результат зависит только от его входных данных. «повторно входящий» означает, что его безопасно вызывать, пока он уже выполняется (например, из обработчика прерывания) — он не имеет внутренних статических данных.

22.05.2013
  • @larsmans: это не вычитание нуля, это вычитание нулевого указателя. 22.05.2013
  • Является ли он более неопределенным (если это имеет смысл), чем прямое приведение указателя к uintptr_t? 22.05.2013
  • Итак, он возвращает номер ячейки памяти b/n, адрес 0 и адрес p.Oh k thans man... 22.05.2013
  • @Mehrdad: это дало бы другое значение; вероятно, смещение byte от нуля, а не смещение word. 22.05.2013
  • @Mehrdad Да, приведение к uintptr_t вовсе не является неопределенным поведением. Результат определяется реализацией, но в этом нет UB. 22.05.2013
  • @Mehrdad: Но да, (uintptr_t)p / sizeof(int) будет более определенным (пока uintptr_t существует): определяется реализацией с примечанием, что сопоставление не должно удивлять тех, кто знает структуру адресации базовой машины. 22.05.2013

  • 2

    Вычитание двух указателей возвращает целое число типа ptrdiff_t, смещение между двумя указателями, в единицах sizeof(int). Может ли это быть правильно приведено к int, зависит от реализации. Вычитание нулевого указателя приводит к неопределенному поведению.

    Это кажется сложным и ненадежным способом преобразования указателя в целое число. Лучший способ — преобразовать его в intptr_t и разделить на sizeof(int).

    22.05.2013
  • Его первоначальный ответ утверждал, что он вернул ptrdiff_t. Это все, что он сказал. Он редактировал это уже миллиард раз. 22.05.2013

  • 3

    Я предполагаю, что человек, написавший эту функцию, думает, что он умнее, чем он есть на самом деле. Он не делает ничего, что простой актерский состав не сделал бы лучше.

    Что касается "чистого" и "реентерабельного"...

    Чистая функция — это функция, единственным эффектом которой является возвращаемое значение. Это не вызывает изменения состояния.

    Реентерабельная функция является потокобезопасной. Его можно прервать и вызвать другим потоком без изменения эффекта исходного вызова.

    Все чистые функции реентерабельны.

    Тот факт, что это чистая функция, очевиден, как и ее реентерабельность. Комментарий бессмысленный, как и сама функция.

    22.05.2013
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..