草庐IT

c - 这个 linux 内核宏中的 BIT() 是什么意思?

我正在浏览Linux内核代码,在filehid.h中,HID_QUIRK_ALWAYS_POLL宏定义为:#defineHID_QUIRK_ALWAYS_POLLBIT(10)BIT(10)是什么意思?我对C不是很熟悉,但据我所知(和研究),没有这样的位操作函数。 最佳答案 看起来您可以在包含的第一个头文件中找到答案,即bitops.h!#defineBIT(nr)(1UL即BIT为指定的位数定义了一个位掩码,从0(最低有效位或最右边的位)到适合unsignedlong的任何值。所以BIT(10)应该评估为1024的数值(即1)。

Linux 内核代码中的 C 宏扩展

在用C编写代码时,我通常会忽略使用宏,但我认为我了解它们的基础知识。当我阅读linux内核中list的源代码时,我看到了这样的东西:#defineLIST_HEAD_INIT(name){&(name),&(name)}#defineLIST_HEAD(name)\structlist_headname=LIST_HEAD_INIT(name)(您可以从here.访问代码的剩余部分)我不理解LIST_HEAD_INIT中&符号的功能(我不认为它们是这里操作数的地址),因此在代码中使用LIST_HEAD_INIT。如果有人能启发我,我将不胜感激。 最佳答案

c - Linux 中的 IS_ERR() 宏

在了解如何编写设备驱动程序时,我遇到了IS_ERR()宏。但我找不到它是如何工作的。我已经包含以下代码:majorNumber=register_chrdev(0,DEVICE_NAME,&fops);if(majorNumber那么IS_ERR()宏扩展到什么以及它是如何执行的。 最佳答案 测试提供的指针是否应被视为错误值。它不检查指针是否有效。在您的代码中,IS_ERR用于检查class_create是否成功创建了ebbcharClass。如果发生错误,请注销字符驱动程序并发出错误信号。您可以在err.h中找到宏和内联函数

c - 对齐宏内核

我无法理解这个宏的作用。这些是在linux-kernel中定义的,但我的怀疑与此无关。我无法理解(((x)+(mask))&~(mask))行的作用。#defineALIGN(x,a)__ALIGN_MASK(x,(typeof(x))(a)-1)#define__ALIGN_MASK(x,mask)(((x)+(mask))&~(mask))感谢任何帮助。 最佳答案 假设你有一个数字:0x1006出于某些原因,您希望将其对齐到4字节边界。对于4字节边界,您知道对齐值是0x1000、0x1004、0x1008等。然后您还知道0x10

c - Linux 内核中的类型检查宏是如何工作的?

Linux内核4.16的文件include/linux/typecheck.h包含这段代码。#definetypecheck(type,x)\({type__dummy;\typeof(x)__dummy2;\(void)(&__dummy==&__dummy2);\1;\}检查x是否与参数type的类型相同。但我无法理解这行:(void)(&__dummy==&__dummy2);比较两个变量的首地址有什么帮助? 最佳答案 这使用了两个GCC扩展——表达式语句({...})和typeof()。展开式的第一行声明了一个名为type的

c - 如何使用 gdb 查看宏扩展的每一行的逐步执行

我有一个宏,其定义大约有50行,并且有很多“ifelse”语句。此宏def'n出现在.h文件中。我正在运行“TUI模式下的gdb”,但是当执行到该宏时,代码窗口变为空白,仅在执行宏代码后才返回。我想逐行执行完整的宏代码。请让我知道如何做到这一点(一种方法是用代码中的定义替换宏,然后重新编译它。我不想使用这个选项,因为我的代码中有几个这样的宏)。任何帮助将不胜感激。期待得到这个问题的解决方案。请让我知道这个问题是否有其他方法而不是使用预处理文件?我有一个代码运行到数百个.c和.h文件中。 最佳答案 一种选择是完全预处理您的C文件,展开

c - 为什么这个宏被定义为({ 1; })?

在Linux的多个ARM后端中,我在文件clkdev.h中看到这个宏定义:#define__clk_get(clk)({1;})参见示例./arch/arm/mach-versatile/include/mach/clkdev.h这个宏正在使用GCC扩展StatementsandDeclarationsinExpressions后来这个宏被用在文件./drivers/clk/clkdev.c中,在函数clk_get_sys()中if(cl&&!__clk_get(cl->clk))cl=NULL;我想知道为什么不在这里使用一个简单的宏:#define__clk_get(clk)(1)编

performance - gcc 可能不太可能使用宏

我正在编写一段关键的代码,其逻辑大致如下if(expressionistrue){//dosomethingwithextremelylowlatencybeforethenukeblowsup.Thisbranchisenteredrarely,butitisthemostimportantcase}else{//dounimportantthingthatdoesntreallymatter}我正在考虑在表达式周围使用likely()宏,因此当它到达重要分支时,我会得到最小的延迟。我的问题是,它的用法与建议的宏名称完全相反,因为我选择unlikely分支进行预取,即不太可能发生重要

c++ - 预处理器宏作为其他宏的参数

以下C++代码编译并作为程序员在GCC(4.0.4)上运行#defineFOO(x,y,z)((x)*(y)*(z))#defineBAR(x)FOO(x,1)#defineBAZ3,7intmain(){returnBAR(BAZ);/*interpretedasreturn((3)*(7)*(1));*/}但是,宏在MicrosoftVisualC++Express2010上会导致错误:main.cpp(7):warningC4003:notenoughactualparametersformacro'FOO'main.cpp(7):errorC2059:syntaxerror:'

c++ - 何时以及为什么使用#define 宏(x)而不是函数?

看到thisquestion让我想知道为什么这种方法(玩具示例):#definefoo(x)bar[x]=0会比函数更受欢迎:voidfoo(unsignedx){bar[x]=0;}在上面链接的问题之前,我之前只在PolarSSL库中看到过一次,我认为它是某种优化,并尽量不去想太多。我假设使用预处理器宏将“调用”替换为“(非)函数体”,无论它存在于何处;而void函数可能会或可能不会被编译器优化,因此可能会导致一两个小而简单的操作产生大量分支。还有其他好处吗?什么时候首选宏方法,什么时候更信任编译器? 最佳答案 首先,我希望你的宏