Какова функция "(void) (& _min1 == & _min2)" в макросе min в kernel.h? - PullRequest
58 голосов
/ 08 апреля 2011

In 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);. Это какая-то проверка типа или что-то в этом роде?

Ответы [ 6 ]

58 голосов
/ 08 апреля 2011

Заявление

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

является гарантированным "неоперативным".Таким образом, единственная причина, по которой он существует, заключается в его побочных эффектах.

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

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

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

18 голосов
/ 03 ноября 2014

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

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

11 голосов
/ 03 ноября 2014

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

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

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

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

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

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

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

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

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

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

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

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

6 голосов
/ 08 апреля 2011

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

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

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

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

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

4 голосов
/ 03 ноября 2014

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

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

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

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

0 голосов
/ 08 апреля 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...