What does this code mean?

I found a code segment. I do not understand. The __rem variable seems to be useless at all. The following line is not doing useful work yet:

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

The entire code segment is as follows:

 #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); } 

Why is the code useless here?

+6
source share
1 answer

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

See Linux/include/asm-generic/div64.h :

No need to compare with a pointer. for type safety checks (n must be 64 bits)

Example:

n should be int , but it's short

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

We get a warning: comparison of distinct pointer types lacks cast

Compiled with: gcc -o main main.c

Compiler Version: gcc (GCC) 4.9.2 20141101 (Red Hat 4.9.2-1)

Output:

Comparing pointers is not useless. It generates a warning if the variable passed to do_div() is of the wrong type.

2. __rem

The code surrounded by braces is an expression of the gcc expression. __rem is, so to speak, the return value of do_div() .

Example:

 #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; } 

Output: 9 / 2 = 4, reminder = 1

In the above example, c = do_div(a, b) equivalent to c = ({int rem = a % b; a /= b; rem;}) .

Output:

__rem not useless, this is the "return value" of do_div() .

+12
source

All Articles