Что такое функция "(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 56

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 хаков.