Что такое функция "(void) (&min1 == & min2)" в макросе min в ядре.ч?
на ядра.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 ответов:
заявление
(void) (&_min1 == &_min2);
является гарантированным "no-op". Так что единственная причина, по которой он есть, - это его побочные эффекты.
но заявление не имеет никаких побочных эффектов!
: это заставляет компилятор выдавать диагностику, когда типыx
иy
не совместимы.
Обратите внимание, что тестирование с_min1 == _min2
неявно преобразует одно из значений в другой тип.так, я думаю, что это то, что он делает. он проверяет, во время компиляции, что типы
x
иy
совместимость.
код включить / linux / ядро.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 что объясняет:
Это связано с проверкой типов.
создание простой программы:
int x = 10; long y = 20; long r = min(x, y);
выдает следующее предупреждение: предупреждение: сравнение различных типов указателей не имеет приведения
нашли ответа здесь
"Это связано с проверкой типов. Создание простой программы:
int x = 10; long y = 20; long r = min(x, y);
выдает следующее предупреждение: предупреждение: сравнение различных типов указателей не имеет приведения"
ядро Linux полно таких вещей (безвозмездные GCC-специфические хаки ради "безопасности типа" и других подобных соображений), и я бы счел это очень плохой практикой и призвал вас не следовать ей, если кто-то не требует от вас этого.
pmg прав о цели взлома, но любой здравомыслящий человек определит
min
Как((x)<(y)?(x):(y))
.обратите внимание, что определение ядра исключает многие правильные использования, например, где один аргумент
int
и еще этоlong
. Я подозреваю, что они действительно хотели исключить несоответствия signedness, где напримерmin(-1,1U)
это 1. Лучший способ утверждать это - использовать утверждение времени компиляции для((1?-1:(x))<0)==((1?-1:(y))<0)
. Обратите внимание, что это не требует каких-либо специфичных для gcc хаков.