beautiful C code(updating)

xiaoxiao2021-02-28  91

记录看到过的让人眼前一亮的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);
转载请注明原文地址: https://www.6miu.com/read-30469.html

最新回复(0)