博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

linux kernel

热爱linux kernel 的学习, 才能真正学习到真正的操作系统技术。 还要配合学习 系统结构和 微机原理才行啊 欢迎访问我的旧blog; zhanglinbao.blogchina.com 里面的GDB的东西值得一看. 本人的blog 多半都是自己学习记录和文档, 如有转载,请指明出处,并mail bob_zhang2004@163.com 告知转载地址 。
kernelChina.cublog.cn


【原创】从kernel和其他opensource 扒出来的常见的宏,对写应用程序相当有用
比如比较两个数的大小 : 一般我们都习惯了这样写:
#define MAX(a,b) (((a)>(b))?(a)b)) //实际上宏参数计算两次
可是宏是有副作用的, 比如下面这个例子: MAX(a++,b) 又如何呢?
所以kernel里面的gcc扩展提供了很好的办法:
 

#define MAX_CHECK(x,y)     \ //宏参数仅仅计算一次

({                \
    typeof(x) __x = (x);    \
    typeof(y) __y = (y);    \
    (void) (&__x == &__y);    \
    (__x>__y) ?__x:__y    ;\
})注意上面的是语句表达式(就是 用() 括起来) , 当if(MAX_CHECK(10,20) ) 是没有副作用的。 typeof 是个宏, 取出变量的类型

当然上面的宏 按照kernel里面的写法也可以写成这样:

#define MAX_CHECK2(x,y)     \
do{                \
    typeof(x) __x = (x);    \
    typeof(y) __y = (y);    \
    (void) (&__x == &__y);    \
    (__x>__y) ?__x:__y    ;\
}while(0) //注意可没有;但是用法就不一样了,语句表达返回的是个值 , 但是 这点用 do {} while(0) 格式就不幸了。

比如 你可以这样 max = MAX_CHECK(a,b);
但是这样就错了: max = MAX_CHECK2(a,b) ; 编译就出错了。
但是如果 一行里面直接写 MAX_CHECK2(a,b) 肯定就没有问题了。

---

下面是就是聪kernel里面扒出来的:

 


#define ARRAY_SIZE(X) ((sizeof((X)))/(sizeof((X)[0])))
#define ALIGN(x,a)         (((x)+(a)-1) & (~((a)-1)))
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

#define abs(x) ({                    \
        int __x = (x);                \
        (__x < 0) ? -__x : __x;        \
    })
    

//太有用的宏了, 一定要掌握
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

//也非常有用

/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:    the pointer to the member.
 * @type:    the type of the container struct this is embedded in.
 * @member:    the name of the member within the struct.
 *
 */

#define container_of(ptr, type, member) ({            \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})
        
        
//#define container_of(ptr,type,member)

//({                                                            \

//    const typeof(((type *)0)->member) *__mptr = (ptr);    \ //仅仅计算一次

//    (type *)((char *)__mptr - offsetof(type,member)) ;        \

//})

    


/**
 * list_entry - get the struct for this entry
 * @ptr:    the &struct list_head pointer.
 * @type:    the type of the struct this is embedded in.
 * @member:    the name of the list_struct within the struct.
 */

#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

//#define abs(x)    ((x) > 0)?(x):(-(x))


/*
 * ..and if you can't take the strict
 * types, you can specify one yourself.
 *
 * Or not use min/max at all, of course.
 */

#define MIN_T(type,x,y) \
    ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
#define MAX_T(type,x,y) \
    ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })

#define MAX(x,y)    ( (x)>(y)?(x):(y) )
#define MAX_CHECK(x,y)     \
({                \
    typeof(x) __x = (x);    \
    typeof(y) __y = (y);    \
    (void) (&__x == &__y);    \
    (__x>__y) ?__x:__y    ;\
})

发表于: 2007-05-10 ,修改于: 2007-05-10 19:12,已浏览1690次,有评论2条 推荐 投诉


网友评论
内容:
有朋友问: 
({ \
typeof(x) __x = (x); \
typeof(y) __y = (y); \
(void) (&__x == &__y); \
(__x>__y) ?__x:__y ;\
}) 
其中(void) (&__x == &__y);的目的是什么? 

检查两个变量的类型是否相同,如果不相同,编译的时候会有警告。
比如 
int a=8;
flat b = 1.5 ; 

编译的时候,就会有warning ,弥补了编译器不检查宏参数的问题。
bob_zhang2004 评论于:2007-05-10 13:29:17 (222.92.90.★)
内容:
顶你
本站网友评论于:2007-07-05 16:44:42 (124.17.17.★)

发表评论