Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1638724
  • 博文数量: 197
  • 博客积分: 10046
  • 博客等级: 上将
  • 技术积分: 1983
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-07 12:36
个人简介

在外企做服务器开发, 目前是项目经理, 管理两个server开发的项目。不做嵌入式好久了。

文章分类
文章存档

2011年(2)

2010年(6)

2009年(18)

2008年(30)

2007年(100)

2006年(41)

分类: LINUX

2007-08-31 17:27:10

kernel 里面有用的宏,供参考

kernel里面扒出来的检查变量类型的宏。


第一种实现实现 :
/*
* Check at compile time that something is of a particular type.
* Always evaluates to 1 so you may use it easily in comparisons.
*/
#define typecheck(type,x) \
({        type __dummy; \
        typeof(x) __dummy2; \
        (void)(&__dummy == &__dummy2); \
        1; \
})


第二种实现:

#define TYPE_EQUAL(n, type) \
                __builtin_types_compatible_p(typeof(n), type *)


------------

且看kernel里面的例子:
关于  montavista-kernel-2.6.18_pro500

QUOTE:
#define PICK_OP(op, lock)                                                \
do {                                                                        \
        if (TYPE_EQUAL((lock), raw_spinlock_t))                                \
                __spin##op((raw_spinlock_t *)(lock));                        \
        else if (TYPE_EQUAL(lock, spinlock_t))                                \
                _spin##op((spinlock_t *)(lock));                        \
        else __bad_spinlock_type();                                        \
} while (0)

#define spin_lock_irq(lock)        PICK_OP(_lock_irq, lock)
#define spin_lock_bh(lock)        PICK_OP(_lock_bh, lock)
 
 
————————————————————————————————————————————
 
 
在kernel 里面不太好验证:

我写了一个简单的程序来玩玩:
GNU的扩展语法真的比较强, 必 ANSI C强多了。

功能需求: 实现一个通用的打印函数, 可以打印所有的变量。

QUOTE:
#include
#include

#define TYPE_EQUAL(n, type) \
                __builtin_types_compatible_p(typeof(n), type *)


#define PICK_OP_PRINT(op, n)                                                \
do {                                                                \
        if (TYPE_EQUAL((n), int))                                        \
                printf("int number=%d\n",*n);                                \
        else if (TYPE_EQUAL(n, long))                                        \
                printf("long number=%ld\n",*n);                                \
        else                                                         \
                printf("error\n");                                        \
} while (0)

#define printtype(n)        PICK_OP_PRINT(op, n)


int main(void)
{
        int a = 20;
        printtype(&a);
       
        long b = 100000000;
        printtype(&b);
       
        float c = 3.6L;
        printf("float c=%f\n",c);
        printtype(&c);
       
        return 0;
}

输出结果如下:

QUOTE:
[root@bobzhanglinux debug]# gcc spinlock.c
[root@bobzhanglinux debug]# ./a.out
int number=20
long number=100000000
float c=3.600000
error
[root@bobzhanglinux debug]#
 
 
 
----------------------------------------
我们在kernel的代码里面经常会看到定义宏的时候, 会有这样的格式:

#define A ({ a })   一般都是定义类函数宏的时候 才这样的,  这样在里面可以加这些语句体 , 然后返回一些值 ,
最后, 不要return , 从来看不到return这样的字样 。 具体的我们也没有必要深究的。 只要模仿着写一些常用的好类函数宏, 就好了。

比如下面的例子:

#define PICK_OP_PRINT(op, n)                                                \
({                                                                        \
        if (TYPE_EQUAL((n), int))                                        \
                printf("int number=%d\n",*n);                                \
        else if (TYPE_EQUAL(n, long))                                        \
                printf("long number=%ld\n",*n);                                \
        else                                                                 \
                printf("error\n");                                        \
})




象上面这个类函数宏,也可以写成这个样子:

#define PICK_OP_PRINT(op, n)                                                \
do {                                                                        \
        if (TYPE_EQUAL((n), int))                                        \
                printf("int number=%d\n",*n);                                \
        else if (TYPE_EQUAL(n, long))                                        \
                printf("long number=%ld\n",*n);                                \
        else                                                                 \
                printf("error\n");                                        \
} while (0)

以上情况,都是适合不要返回值的情况下。
--------------------

如果要返回值, 我看就只能用 ({})  
就不能用do{}while(0)  ,这种比较适合写类函数宏

----

比如下面的例子:就只能用 ({}) 了。
要返回一个值:
#define PICK_OP2_RET(op, lock, flags)                                        \
({                                                                        \
        unsigned long __ret;                                                \
                                                                        \
        if (TYPE_EQUAL((lock), raw_spinlock_t))                                \
                __ret = __spin##op((raw_spinlock_t *)(lock), flags);        \
        else if (TYPE_EQUAL(lock, spinlock_t))                                \
                __ret = _spin##op((spinlock_t *)(lock), flags);                \
        else __bad_spinlock_type();                                        \
                                                                        \
        __ret;                                                                \
})


阅读(1143) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~