Что означает этот код
Я нашел фрагмент кода. Я этого не понимаю. Кажется, что переменная _ _ 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()
.