这段代码意味着什么

use*_*758 6 c linux-kernel

我找到了一个代码段.我不明白.似乎变量__rem根本没用.下面的行还没有做任何有用的工作:

(void)(((typeof((n)) *)0) == ((uint64_t *)0));   \
Run Code Online (Sandbox Code Playgroud)

整个代码段如下:

#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);
}
Run Code Online (Sandbox Code Playgroud)

为什么这里没用无用的代码?

ser*_*gej 12

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

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

不必要的指针比较用于检查类型安全性(n必须为64位)

例:

n必须是int,但确实如此short

void main()
{
    short n;
    (void)(((typeof((n)) *)0) == ((int *)0));
}
Run Code Online (Sandbox Code Playgroud)

我们收到警告: 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;
}
Run Code Online (Sandbox Code Playgroud)

输出: 9 / 2 = 4, reminder = 1

在上面的例子中,c = do_div(a, b)相当于c = ({int rem = a % b; a /= b; rem;}).

结论:

__rem没有用,它是"回归价值" do_div().