0Day Forums
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()`.