我找到了一个代码段.我不明白.似乎变量__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.(void)(((typeof((n))*)0)==((uint64_t *)0));
请参阅Linux / include / asm-generic / div64.h:
The unnecessary pointer compare is there
to check for type safety (n must be 64bit)
例:
n必须是int,但它很短
void main() { short n; (void)(((typeof((n)) *)0) == ((int *)0)); }
我们收到警告:
不同指针类型的比较缺乏强制转换
编译: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",c); return 0; }
输出:9/2 = 4,提醒= 1
在上面的例子中,c = do_div(a,b)等价于c =({int rem = a%b; a / = b; rem;}).
结论:
__rem并非无用,它是do_div()的“返回值”.