beautiful C code(updating)

记录看到过的让人眼前一亮的C代码,通常是简洁高效的一些做法,如果有朋友觉得想要分享代码,欢迎在评论区共享哈。

1、移位操作

在linux-4.4/drivers/usb/dwc2/gadget.c看到

u32 daint, daintmask;

daint &= daintmask;
daint_out = daint >> DAINT_OUTEP_SHIFT;
daint_in = daint & ~(daint_out << DAINT_PUTEP_SHIFT)

通常我们的做法是通过val&0xFFFF这样的语法来获取位元,这种适合mask值固定的情况,但这里的mask是software在运行时配置的,所以就不适合常见的做法了。

2、container_of

通过结构体成员地址获得结构体地址

# define offsetof(typ, memb)     ((unsigned long)((char *)&(((typ *)0)->memb)))

/**
 * 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) );})

通过成员地址ptr-ptr在结构体中的偏移得到结构体变量的地址,说这代码漂亮嘛,其实也谈不上,就是C语言的一种用法,内核中很常见。

3、log2

#define LOG2(x) (((x & 0xaaaaaaaa) ? 1 : 0) + ((x & 0xcccccccc) ? 2 : 0) + \
         ((x & 0xf0f0f0f0) ? 4 : 0) + ((x & 0xff00ff00) ? 8 : 0) + \
         ((x & 0xffff0000) ? 16 : 0))

C语言宏实现的取对数

4、迭代器

这是一份内核搜索某一个class中的device的代码,首先要声明device结构的class(此处为sample_class),然后通过dev_set_name设置device name,再通过device_add告诉kernel。

struct device *dev;
struct class_dev_iter iter;

class_dev_iter_init(&iter, sample_class, NULL, NULL);
while ((dev = class_dev_iter_next(&iter))) {
    if (strcmp(epc_name, dev_name(dev)))
        continue;
    // found,do something
    class_dev_iter_exit(&iter);
err:
    class_dev_iter_exit(&iter);
    return ERR_PTR(ret);
发布了146 篇原创文章 · 获赞 78 · 访问量 53万+

猜你喜欢

转载自blog.csdn.net/abcamus/article/details/72891524