Что означает этот код

Я нашел фрагмент кода. Я этого не понимаю. Кажется, что переменная _ _ rem вообще бесполезна. Строка ниже пока не выполняет никакой полезной работы:

(void)(((typeof((n)) *)0) == ((uint64_t *)0));   

весь сегмент кода выглядит следующим образом:

#define do_div(n,base)  do{             
    uint32_t __base = (base);           
    uint32_t __rem;                 
    (void)(((typeof((n)) *)0) == ((uint64_t *)0));   
    if (((n) >> 32) == 0) {         
        __rem = (uint32_t)(n) % __base;     
        (n) = (uint32_t)(n) / __base;       
    } else                      
        __rem = __div64_32(&(n), __base);   
    __rem;                      
 }while(0)
/* Wrapper for do_div(). Doesn't modify dividend and returns
 * the result, not reminder.
 */
static inline uint64_t lldiv(uint64_t dividend, uint32_t divisor)
{
    uint64_t __res = dividend;
    do_div(__res, divisor);
    return(__res);
}

почему здесь бесполезный код?

1 ответов


1. (void)(((typeof((n)) *)0) == ((uint64_t *)0));

посмотреть Linux/include/asm-generic/div64.h:

ненужный указатель сравнить есть для проверки безопасности типа (n должно быть 64bit)

пример:

n должно быть int, но это short

void main()
{
    short n;
    (void)(((typeof((n)) *)0) == ((int *)0));
}

мы получаем предупреждение: comparison of distinct pointer types lacks cast

составлено с помощью:gcc -o main main.c

версия компилятора : gcc (GCC) 4.9.2 20141101 (Red Hat 4.9.2-1)

вывод:

сравнение указателей не бесполезно. Он генерирует предупреждение, если переменная передана в do_div() имеет неверный тип.

2. __rem

код, окруженный фигурными скобками, является выражением оператора gcc. __rem это, так сказать, возвращаемое значение do_div().

пример:

#include <stdio.h>

#define do_div(n,base)  ({ \
    int __rem = n % base;  \
    n /= base;             \
    __rem;                 \
})

int main()
{
    int a = 9;
    int b = 2;
    int c = 0;

    printf("%i / %i = ", a, b);
    c = do_div(a, b);
    printf("%i, reminder = %i\n", a, c);
    return 0;
}

выход: 9 / 2 = 4, reminder = 1

в приведенном выше примере,c = do_div(a, b) эквивалентно c = ({int rem = a % b; a /= b; rem;}).

вывод:

__rem не бесполезно, это "возвращаемое значение"do_div().