Какова функция "(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);. Это какой-то тип проверки или что-то еще?

Ответы

Ответ 1

Утверждение

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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

и включает в себя:

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

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

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

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

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

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

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

Дает следующее предупреждение: предупреждение: сравнение отдельного указателя не хватает литых

Ответ 4

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

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

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

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

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

Ответ 5

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

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

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

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

Ответ 6

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

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

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