文件路径: uapi/linux/const.h 文件内容如下: /* const.h: Macros for dealing with constants. */#ifndef _LINUX_CONST_H#define _LINUX_CONST_H/* Some constant macros are used in both assembler and * C code. Therefore we cannot annotate them alw
文件路径:
uapi/linux/const.h
文件内容如下:
/* const.h: Macros for dealing with constants. */
#ifndef _LINUX_CONST_H
#define _LINUX_CONST_H
/* Some constant macros are used in both assembler and
* C code. Therefore we cannot annotate them always with
* 'UL' and other type specifiers unilaterally. We
* use the following macros to deal with this.
*
* Similarly, _AT() will cast an expression with a type in C, but
* leave it unchanged in asm.
*/
#ifdef __ASSEMBLY__
#define _AC(X,Y)X
#define _AT(T,X)X
#else
#define __AC(X,Y)(X##Y)
#define _AC(X,Y)__AC(X,Y)
#define _AT(T,X)((T)(X))
#endif
#define _BITUL(x)(_AC(1,UL) << (x))
#define _BITULL(x)(_AC(1,ULL) << (x))
#endif /* !(_LINUX_CONST_H) */具体的就不翻译啦,大概就是说在有些常量宏同时在汇编和C代码中出现,这样会出现问题,所以就用这个文件中定义的宏对这类问题进行处理,这里处理的是UL, ULL这两个宏。在着重解释UL、ULL、_AC(X, Y)、_AT(T, X)。
这理的UL、ULL,就是常见的C语言常量后缀,比如什么L、U,大家应该见过。因为出现UL也会成为一常量宏,所以在此进行相关处理。
_AC(X, Y)的作用就是产生对应的X,但是在__ASSEMBLY__和非__ASSEMBLY下有所不同。在__ASSEMBLY__下直接反回X,在非__ASSEMBLY__下返回X与Y的拼接符号。
_AT(T, X)在此处的作用相当于函数调用,其中T可以为函数名或者函数指针,X为相应该的参数表,如下:
#include
#define _AT(T,X)((T)(X))
int func(int x)
{
printf("x = %d\n", x);
}
int main()
{
_AT(func, 1);//此处使用X为函数名,若为函数指针也类似。
}发现写博客可以加深理解咯,小伙伴们都来写吧。欢迎指正啦~~