О typecheck в ядре linux

#define typecheck(type,x) \
({      type __dummy; \
        typeof(x) __dummy2; \
        (void)(&__dummy == &__dummy2); \
        1; \
}

файл typecheck.h содержит эти коды. я знаю этот код проверяет, является ли x тот же тип, что и параметр type. но я не могу понять коды о

 (void)(&__dummy == &__dummy2);

почему этот способ может решить это? первый адрес двух переменных может иметь смысл? спасибо за Ваш ответ. или скажите мне, что я должен изучить некоторые моменты.

Ответ 1

Сравнение указателей с несовместимыми типами является нарушением ограничений и требует, чтобы компилятор выдавал диагностику. См. 6.5.9 Операторы равенства:

Ограничения

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

  • оба операнда имеют арифметический тип;
  • оба операнда являются указателями на квалифицированные или неквалифицированные версии совместимых типов;
  • один операнд является указателем на объект или неполным типом, а другой - указателем на квалифицированную или неквалифицированную версию void; или
  • один операнд является указателем, а другой - константой нулевого указателя.

и 5.1.1.3 Диагностика:

Соответствующая реализация должна выдавать, по меньшей мере, одно диагностическое сообщение (идентифицированное определенным образом), если блок трансляции или блок перевода содержит нарушение любого синтаксического правила или ограничения, даже если поведение также явно указано как undefined или определяется реализацией. Диагностические сообщения не должны возникать при других обстоятельствах.

Ответ 2

Это использует два расширения GCC — выражения ({ ... }) и typeof().

  • Первая строка расширения объявляет переменную именованного типа type.
  • Вторая строка расширения объявляет переменную того же типа, что и переменная или выражение x.
  • Третья строка сравнивает два указателя, которые будут соответствовать только совпадению типов двух фиктивных переменных, генерируя предупреждение о несоответствии указателя (или ошибку при компиляции с помощью -Werror).
  • Последняя строка (содержащая 1) - это значение выражения — эквивалентно true.

Итак, вы получаете предупреждение/ошибку компиляции, если тип x не совпадает с типом named.

Пример кода:

#include <stdio.h>

#define typecheck(type,x) \
({      type __dummy; \
        typeof(x) __dummy2; \
        (void)(&__dummy == &__dummy2); \
        1; \
})

int main(void)
{
    int x;
    if (typecheck(int, x))
        printf("int x OK\n");
    if (typecheck(double, x))
        printf("double x OK\n");
    return(0);
}

Сообщение компиляции:

$ /usr/bin/gcc -O3 -g -std=gnu99 -Wall -Wextra xx.c -o xx  
xx.c: In function ‘main’:
xx.c:15: warning: comparison of distinct pointer types lacks a cast
$

Обратите внимание, что, поскольку я не использовал -Werror, код скомпилировал "OK". Вывод:

int x OK
double x OK