Какова функция «(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-специфических хаков.

  • Шпилька в Linux
  • Как читать / записывать файлы в модуле ядра Linux?
  • Как уменьшить неизменяемые и непредсказуемые страницы в Linux
  • Сообщения ядра ядра на другой процесс по мере их возникновения
  • Какая польза от while (0), когда мы определяем макрос?
  • Почему код ядра / stream, выполняемый в контексте прерывания, не может спать?
  • Возможно ли раньше сделать прерывание убийцы OOM раньше?
  • Обращение с ARM TrustZones
  • Radeon HD6570 работает только в ядре Linux 3.6.7
  • Ядро Linux
  • Понимание макроса container_of в ядре Linux
  • Давайте будем гением компьютера.