Какова функция «(void) (& _min1 == & _min2)» в мини-макросе в kernel.h?

В kernel.h min определяется как:

#define min(x, y) ({ \ typeof(x) _min1 = (x); \ typeof(y) _min2 = (y); \ (void) (&_min1 == &_min2); \ _min1 < _min2 ? _min1 : _min2; }) 

Я не понимаю, что строка (void) (&_min1 == &_min2); делает. Это какой-то тип проверки или что-то еще?

Заявление

 (void) (&_min1 == &_min2); 

является гарантированным «no-op». Поэтому единственная причина, по которой это происходит, связана с ее побочными эффектами.

Но утверждение не имеет побочных эффектов!

Однако: он заставляет компилятор выдать диагностику, когда типы x и y несовместимы .
Обратите внимание, что тестирование с помощью _min1 == _min2 неявно преобразует одно из значений в другой тип.

Итак, я думаю, вот что он делает. Он проверяет во время компиляции, что типы x и y совместимы .

Код в include / linux / kernel.h относится к этому как «ненужное» сравнение указателей. Это на самом деле строгая проверка типа, гарантирующая, что типы x и y одинаковы.

Несоответствие типа здесь приведет к ошибке компиляции или предупреждению.

Это обеспечивает проверку типов, равенство между указателями должно быть между совместимыми типами, и gcc предоставит предупреждение для случаев, когда это не так.

Мы видим, что равенство между указателями требует, чтобы указатели были совместимыми типами из стандартного раздела проекта C99 6.5.9 Операторы равенства, которые гласят:

Одно из следующего:

и включает:

оба операнда являются указателями на квалифицированные или неквалифицированные версии совместимых типов;

и мы можем найти совместимый тип из раздела 6.2.7 Совместимый тип и составной тип, который гласит:

Два типа имеют совместимый тип, если их типы одинаковы

Это обсуждение osnews также охватывает это, и оно было вдохновлено взломами GCC в статье ядра Linux, которая имеет тот же пример кода. В ответе говорится:

имеет отношение к проверке типов.

Создание простой программы:

 int x = 10; long y = 20; long r = min(x, y); 

Предоставляет следующее предупреждение: предупреждение: сравнение различных типов указателей не содержит приведения

См. http://www.osnews.com/comments/20566, который объясняет:

Это связано с проверкой typechecking.

Создание простой программы:

 int x = 10; long y = 20; long r = min(x, y); 

Предоставляет следующее предупреждение: предупреждение: сравнение различных типов указателей не содержит приведения

Найден ответ здесь

«Это связано с проверкой typechecking. Создание простой программы:

 int x = 10; long y = 20; long r = min(x, y); 

Предоставляет следующее предупреждение: предупреждение: для сравнения различных типов указателей отсутствует листинг ”

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

pmg прав насчет цели взлома, но любой здравомыслящий человек определял бы min as ((x)<(y)?(x):(y)) .

Обратите внимание, что определение ядра исключает много правильных применений, например, если один аргумент является int а другой long . Я подозреваю, что они действительно хотели исключить несоответствия подписи, где, например, min(-1,1U) равно 1. Лучшим способом утверждать это было бы использование утверждения времени компиляции для ((1?-1:(x))<0)==((1?-1:(y))<0) . Обратите внимание, что это не требует каких-либо gcc-специфических хаков.

  • Что делает request_mem_region () на самом деле и когда это необходимо?
  • Каковы последствия макросов linux __user?
  • В чем разница между module_init и subsys_initcall при инициализации драйвера?
  • Сообщения ядра ядра на другой процесс по мере их возникновения
  • В чем разница между vmalloc и kmalloc?
  • Что такое инструкции IN & OUT для x86?
  • Как использовать сокет netlink для связи с модулем ядра?
  • Где я могу найти linux-kernel-headers-xxxx для SUSE?
  • функция cat вызывает read () бесконечное время
  • Почему код ядра / stream, выполняемый в контексте прерывания, не может спать?
  • Возможно ли раньше сделать прерывание убийцы OOM раньше?
  • Interesting Posts

    Многократное наследование Java

    Sshfs с пересылкой x?

    форматировать исключение бросания streamа “thread_resource_error: ресурс временно недоступен”

    Чтение в файле JSON с использованием Swift

    Как заставить кнопки Google минимизировать, восстанавливать и закрывать кнопки Google, аналогичные другим программам?

    Как вы обрабатываете ресурсы в MATLAB безопасным образом? (например, «попробуй … наконец»)

    jquery save json объект данных в cookie

    Работа модуля с отрицательными номерами

    Предварительный просмотр фотографий в Windows 10

    Сообщение LogCat: Ресурсы служб Google Play не найдены. Проверьте конфигурацию проекта, чтобы убедиться, что ресурсы включены.

    Как настроить кнопку переключателя?

    Java Date rounding

    Используя средство командной строки cURL на Mac, что я могу сделать с этим скриптом, чтобы попросить его получить данные запаса, которые возвращаются без запятых?

    Обновление пользовательского интерфейса из разных streamов в JavaFX

    Android: Я использую библиотеку AChartEngine для графиков, но не могу интегрировать графический вид артангина с помощью android xml?

    Давайте будем гением компьютера.