What does this code mean - Printable Version +- 0Day Forums (https://0day.red) +-- Forum: Coding (https://0day.red/Forum-Coding) +--- Forum: C & C++ (https://0day.red/Forum-C-C) +--- Thread: What does this code mean (/Thread-What-does-this-code-mean) |
What does this code mean - ecumenism363255 - 07-27-2023 I found a code segment. I do not understand it. It seems that the variable __rem is useless at all. The line below does not do any useful work yet: (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ The whole code segment is as below: #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 useless code here? RE: What does this code mean - septile261928 - 07-27-2023 #1. `(void)(((typeof((n)) *)0) == ((uint64_t *)0));` See `Linux/include/asm-generic/div64.h`: > The unnecessary pointer compare is there > to check for type safety (n must be 64bit) **Example:** `n` must be `int`, but it is `short` void main() { short n; (void)(((typeof((n)) *)0) == ((int *)0)); } We get the 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)` **Conclusion:** The pointer compare is not useless. It generates a warning if the variable passed to `do_div()` has a wrong type. #2. __rem The code surrounded by braces is a gcc statement-expressions. `__rem` is, so to say, 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 example above, `c = do_div(a, b)` is equivalent to `c = ({int rem = a % b; a /= b; rem;})`. **Conclusion:** `__rem` is not useless it is the "return value" of `do_div()`. |