首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

避免这7个误区,才能让【宏】削铁如泥

语法错误 当使用参数调用宏时,会将参数替换为宏主体,并与其他输入文件一起检查结果,以进行更多的宏调用,可以将部分来自宏主体和部分自变量的宏调用组合在一起。...参数预扫描处理 宏参数在被替换为宏主体之前必须经过完全宏扩展,替换后,将再次扫描整个宏主体,包括替换的参数,以查找要扩展的宏。...如果按照给定的方式替换了参数,并且没有进行预扫描,则剩余的单个扫描将找到相同的宏调用并产生相同的结果。 预扫描处理在以下三种特殊情况下有大的作用。...预扫描会导致发生预期的结果。 如果没有预扫描,f(1)本身将被替换为参数,并且f的内部使用将在主扫描期间作为间接自引用出现,并且不会扩展。...参数中使用的宏,其扩展名包含未屏蔽的逗号。 这可能导致使用错误数量的参数调用在第二次扫描时扩展的宏。

1.3K20

Memwatch使用说明

mwSetAriFunc: 设置“Abort, Retry, Ignore”发生时的MemWatch调用的函数.当这样设置调用的函数地址时,实际的错误消息不会打印出来,但会作为一个参数进行传递。...注意retry时,会导致表达式重新求值. MemWatch有个默认的ARI处理器。默认是关闭的,但你能通过调用mwDefaultAri()开启。...同时,设置ARI函数也会导致MemWatch不将ARI的错误信息写向标准错误输出,错误字符串而是作为’const char *’参数传递到ARI函数. mwSetAriAction: 如果没有ARI处理器被指定...mwSetOutFunc: 将输出转向调用者给出的函数(参数即函数地址)。...如果在流程中捕获了程序的异常中断,那么需要调用mwAbort()而不是 mwTerm()。即使有显示的调用mwTerm(),mwAbort()也将终止MemWatch。

1.2K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C++内联函数

    一、内联函数概念 在c++中,预定义宏的概念是用内联函数来实现的,而内联函数本身也是一个真正的函数。 内联函数具有普通函数的所有行为。...唯一不同之处在于内联函数会在适当的地方像预定义宏 一样展开,所以不需要函数调用的开销。因此应该不使用宏,使用内联函数。 在普通函数(非成员函数)函数前面加上inline关键字使之成为内联函数。...这些事预 处理器无法完成的。 内联函数的确占用空间,但是内联函数相对于普通函数的优势只是省去了函数调用时候的压 栈,跳转,返回的开销。我们可以理解为内联函数是以空间换时间。...<< endl; } } 三、内联函数和编辑器 对于任何类型的函数,编译器会将函数类型(包括函数名字,参数类型,返回值类型)放入到 符号表中。...当调用一个内联函数的时候,编译器首先确保传入参数类型是正确匹配的,或者如果类型不 正完全匹配,但是可以将其转换为正确类型,并且返回值在目标表达式里匹配正确类型,或 者可以转换为目标类型,内联函数就会直接替换函数调用

    1.2K40

    FreeRTOS系列第6篇---FreeRTOS内核配置说明

    对于已经删除的RTOS任务,空闲任务可以释放分配给它们的堆栈内存。因此,在应用中应该注意,使用vTaskDelete()函数时要确保空闲任务获得一定的处理器时间。...当堆栈首次创建时,在它的堆栈区中填充一些已知值(标记)。当任务切换时,RTOS内核会检测堆栈最后的16个字节,确保标记数据没有被覆盖。如果这16个字节有任何一个被改变,则调用堆栈溢出钩子函数。...这些宏可以确保RTOS内核升级到V8.0.0或以上版本时,之前的应用代码不用做任何修改。...优先级小于等于这个宏所代表的优先级时,程序可以在中断服务程序中安全的调用FreeRTOS API函数;如果优先级大于这个宏所代表的优先级,表示FreeRTOS无法禁止这个中断,在这个中断服务程序中绝不可以调用任何...configASSERT 断言,调试时可以检查传入的参数是否合法。FreeRTOS内核代码的关键点都会调用configASSERT( x )函数,如果参数x为0,则会抛出一个错误。

    2.9K22

    Objective-C中的预处理器指令与宏

    引 什么是预处理器,跟我有什么关系? 预处理器是在OC源文件编译过程中的一个部分,而且是第一个处理部分,预处理器的预也由此可见。...不信的话我们可以列举一下常见的预处理指令,预处理器有其区别于Objective-C的独特语法,语法形式如下: #指令名 指令参数 有点眼熟了?...同样的要用#endif来作为结束的界限。 诊断 诊断中先说头两个: #ifndef 宏名 #error "发生错误啦" #endif #if XXX #warning "警报!警报!"...预处理器之宏 要知道,宏也是预处理器范畴内的内容,我们用的也很多: // 定义常量值 #define 宏名 值 //定义函数宏 #define 宏名(参数) 代码 // 移除宏 #undef 宏名 宏被定义后...如果函数有多个参数,用逗号分隔开。 定义函数宏的时候,有一个细节要注意,就是要多对参数使用括号: #defind SQUARE(x) ((x) * (x)) 为什么要这么麻烦?

    72330

    控制核心分配:利用CPU亲和性最大化速度和效率

    参数:name可以参看系统调用的宏定义,比如查阅CPU数量的宏为_SC_NPROCESSORS_CONF返回值:如果名称无效,则返回-1,并将errno设置为EINVAL。...返回值:成功时,子进程的PID在父进程中返回,0在子进程中返回。失败时,在父进程中返回-1,不创建子进程,并适当设置errno。错误:错误代码含义EAGAIN遇到系统对线程数量施加的限制。...;描述:syscall()是一个小型库函数,用于调用系统调用,该系统调用的汇编语言接口具有指定数量和指定参数。例如,当调用C库中没有包装函数的系统调用时,使用syscall()非常有用。...CPU_ALLOC_SIZE返回CPU集的大小(以字节为单位),该大小将用于保存范围为0到num_CPUs-1的CPU。该宏提供了可用于下面描述的CPU_*_S()宏中的setsize参数的值。...CPU_SET()中描述了一组用于操作CPU集的宏。sched_setaffinity()将ID为pid的线程的CPU关联掩码设置为掩码指定的值。如果pid为零,则使用调用线程。

    23400

    CC++:程序环境和预处理宏

    ①在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。 ②替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。.../类型作为参数 MALLOC(10, double);//类型作为参数 //预处理器替换之后: (int*)malloc(10 * sizeof(int)); (double*)malloc(10 *...)); 宏相对函数的缺点: ① 每次使用宏的时候,一份宏定义的代码将插入到程序中。...除了非常小的宏之外,程序的长度会大幅度增长 函数代码只出现于一个地方;每 次使用这个函数时,都调用那个 地方的同一份代码 执 行 速 度 更快 存在函数的调用和返回的额外开 销,所以相对慢一些 操 作...函数参数只在函数调用的时候求 值一次,它的结果值传递给函 数。表达式的求值结果更容易预 测。

    64820

    CUDA Study Notes

    8.在一个CUDA程序中,基本的主机端代码主要完成以下任务 (1) 启动CUDA,使用多卡时加上设备号,或者使用cudaDevice()设置GPU装置。...(3)调用device端的kernel程序计算,将结果写到显存相关区域,再回写到内存。 (4)利用CPU进行数据其他处理,释放内存和显存空间。 (5)退出CUDA装置 9....CUT_DEVICE_INIT(argc, argv)和CUT_EXIT(argc,argv) 是cutil.h中的两个宏函数,分别用来启动和退出CUDA环境。...10.昨CUDA_SAFE_CALL()宏函数 调用后的返回值为cudaerr型,用CUT_CHECK_ERROR()宏函数可以接受最后一次的cudaerr_t异常,如果发生异常将输出错误类型,对调试很有帮助...实际在代码编写的时候,>>参数只需要填写两个,分别BLCOKNUM(block数量)和每个block中的线程数THREADNUM。

    83531

    程序环境和预处理

    2.2.3 #define 替换规则 在程序中扩展#define定义符号和宏时,需要涉及几个步骤。 1. 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。...PRINT("%d", 10); 这里只有当字符串作为宏参数的时候才可以把字符串放在字符串中。 1. 另外一个技巧是: 使用 # ,把一个宏参数变成对应的字符串。...//使用 MALLOC(10, int);//类型作为参数 //预处理器替换之后: (int *)malloc(10 * sizeof(int)); 宏和函数的一个对比 属 性 #define...除了非常 小的宏之外,程序的长度会大幅度增长 函数代码只出现于一个地方;每 次使用这个函数时,都调用那个 地方的同一份代码 执 行 速 度 更快 存在函数的调用和返回的额外开 销,所以相对慢一些 操 作...函数参数只在函数调用的时候求 值一次,它的结果值传递给函 数。表达式的求值结果更容易预 测。

    8410

    FreeRTOS(十六):低功耗 Tickless 模式

    根据Cortex-M 内核的SCR(系统控制)寄存器可以选择使用立即休眠还是退出时休眠,当 SCR 寄存器的 SLEEPONEXIT(bit1)位为 0 的时候使用立即休眠,当为 1 的时候使用退出时休眠...线作为事件。...问题二:如何保证下一个要运行的任务能被准确的唤醒? 即使处理器进入了低功耗模式,但是我的中断和应用层任务也要保证及时的响应和处理。中断自然不用说,本身就可以将处理器从低功耗模式中唤醒。...() 使能 Tickless 模式以后当下面两种情况都出现的时候 FreeRTOS 内核就会调用宏portSUPPRESS_TICKS_AND_SLEEP()来处理低功耗相关的工作。...3、宏 configPRE_SLEEP_PROCESSING ()和 configPOST_SLEEP_PROCESSING() 在真正的低功耗设计中不仅仅是将处理器设置到低功耗模式就行了,还需要做一些其他的处理

    3.8K30

    【C语言基础】:预处理详解(二)

    宏的参数是与类型无关的。 利用宏的执行速度短,那是不是以后就只用宏了呢?这明显是不明智的,函数也有着宏所没有的优点: 3. 每次使用宏的时候,⼀份宏定义的代码将插入到程序中。...当你在宏定义中使用 # 运算符时,它会将宏的参数转换为一个字符串字面量。这意味着,当宏被展开时,参数的值会被放在双引号中,成为字符串的一部分。...注意:使用 # 运算符时,应确保宏参数两侧有空格或其他非字母数字字符,否则可能会导致字符串化不正确。...当预处理器遇到 #undef指令时,它会移除指定宏的定义,使得宏名不再代表之前定义的文本。...这里会引发错误,因为MAX已不再定义 四、命令行定义 在C语言编程中,命令行定义指的是通过编译器的命令行参数来定义宏或者设置编译时的选项。

    17510

    【C语言】什么是宏定义?(#define详解)

    在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”. 宏定义是由源程序中的宏定义命令完成的,宏代换是由预处理程序自动完成的....一般而言,预处理器发现程序中的宏后,会用宏等价的替换文本进行替换,如果替换的字符串中还包含宏,则继续替换这些宏....它包含在头文件中。 通过指定结构体类型和成员名称作为参数,offsetof宏会返回该成员在结构体中的偏移量。...除了非常 小的宏之外,程序的长度会大幅度增长 函数代码只出现于一个地方;每 次使用这个函数时,都调用那个 地方的同一份代码 执 行 速 度 更快 存在函数的调用和返回的额外开 销,所以相对慢一些 操 作...函数参数只在函数调用的时候求 值一次,它的结果值传递给函 数。表达式的求值结果更容易预 测。

    66110

    C语言中的宏定义

    当预处理器遇到一个宏定义时,会做一个 “标识符”代表“替换列表”的记录。在文件后面的内容中,不管标识符在任何位置出现,预处理器都会用替换列表代替它。...当宏作为常量使用时,C程序员习惯在名字中只使用大写字母。但是并没有如何将用于其他目的的宏大写的统一做法。由于宏(特别是带参数的宏)可能是程序中错误的来源,所以一些程序员更喜欢使用大写字母来引起注意。...考虑下面的宏: 如下例子:当MK_ID被调用时(比如MK_ID(1)),预处理器首先使用自变量(这个例子中是1)替换参数n。接着,预处理器将i和1连接成为一个记号(i1)。...接着,预处理器会重新检查替换列表,看它是否包含其他宏的调用(在这个例子中,调用了宏PI)。预处理器会不断重新检查替换列表,直到将所有的宏名字都替换掉为止。...每次参数在替换列表中出现时都要放在圆括号中: #define SCALE(x) ((x)*10) 没有括号的话,我们将无法确保编译器会将替换列表和参数作为完整的表达式。

    6.5K10

    SAS宏初步

    宏处理器 标准SAS程序中,提交程序后,SAS就编译并立即执行。...in New Zealand”; 例子 一份关于花店销售的数据,变量为顾客ID,销售日期,花的种类,数量: ?...这样的宏有些限制,因为它只能做一件事。现在结合%let语句,并增加参数使得其更加灵活 宏自动呼叫库 本书中的宏仅在一个程序内部定义和启动。也可以将宏储存在一个中心位置,叫做自动呼叫库,被各个程序分享。...具体来说,将宏作为文件储存在某路径中,或作为分区数据集中的一员。使用MAUTOSOURCE和SASAUTOS=系统选项告诉SAS在哪里查找宏。之后,即使宏没有出现在程序中,也可以启动它了。...7.4 给宏增加参数 参数就是宏的变量,给宏增加参数,在%MACRO语句中的括号内列出宏变量的名字。

    3.2K60

    C中的预编译宏定义

    这一步骤是由预处理器(preprocessor)来完成的. 在源流程序被编译器处理之前, 预处理器首先对源程序中的"宏(macro)"进行处理....但在调用函数宏时, name与(之间可以有空格. e.g. #define mul(x,y) ((x)*(y)) 注意, 函数宏之后的参数要用括号括起来, 看看这个例子: e.g....insert ( a=1, b=2;)  就有问题了: 预处理器会提示出错: 函数宏的参数个数不匹配. 预处理器把","视为参数间的分隔符.  ...调用这样的函数宏时, 传递给它的参数个数要不少于参数列表中参数的个数(多余的参数被丢弃)....再就是调用函数宏是要注意, 不要多给出";". 注意: 函数宏对参数类型是不敏感的, 你不必考虑将何种数据类型传递给宏.

    2.9K40

    【SAS Says】基础篇:SAS宏初步

    幸运的是,宏的基本功能不是那么难理解。本章介绍的最普遍使用的SAS宏语言的特征。 宏处理器 标准SAS程序中,提交程序后,SAS就编译并立即执行。...in New Zealand”; 例子 一份关于花店销售的数据,变量为顾客ID,销售日期,花的种类,数量: ?...这样的宏有些限制,因为它只能做一件事。现在结合%let语句,并增加参数使得其更加灵活 宏自动呼叫库 本书中的宏仅在一个程序内部定义和启动。也可以将宏储存在一个中心位置,叫做自动呼叫库,被各个程序分享。...具体来说,将宏作为文件储存在某路径中,或作为分区数据集中的一员。使用MAUTOSOURCE和SASAUTOS=系统选项告诉SAS在哪里查找宏。之后,即使宏没有出现在程序中,也可以启动它了。 4....给宏增加参数 参数就是宏的变量,给宏增加参数,在%MACRO语句中的括号内列出宏变量的名字。

    3.1K41

    Linux内核13_1-进程切换是对FPU单元的处理_X86

    但是需要内核为进程保存thread.i387中的浮点寄存器值,等到信号处理程序终止时再恢复这些寄存器值。也就是说,允许信号处理程序使用协处理器。...而在__switch_to()宏中,执行__unlazy_fpu宏,并将先前进程的进程描述符作为参数进行传递。...()完成保存这些寄存器的基本工作,如下所示: 将FPU寄存器的内容保存到旧进程的描述符中,然后重新初始化FPU。...但是通过__unlazy_fpu()宏已经设置了cr0协处理器中的TS标志。...因此: 在使用协处理器之前,内核必须调用kernel_fpu_begin(),继而调用save_init_fpu(),保存用户进程的浮点相关寄存器的内容。然后,清除cr0协处理器中的TS标志。

    73720

    FreeRTOS系列第9篇---FreeRTOS任务概述基础篇

    调度器会不断的启动、停止每一个任务,宏观看上去就像整个应用程序都在执行。 作为任务,不需要对调度器的活动有所了解,在任务切入切出时保存上下文环境(寄存器值、堆栈内容)是调度器主要的职责。...FreeRTOS调度器确保处于最高优先级的就绪或运行态任务获取处理器,换句话说,处于运行状态的任务,只有其中的最高优先级任务才会运行。 任何数量的任务可以共享同一个优先级。...堆栈的宽度乘以深度必须不超过size_t类型所能表示的最大值。比如,size_t为16位,则可以表示的最大值是65535。 「pvParameters」:指针,当任务创建时,作为一个参数传递给任务。...「注意:」 被删除的任务,其在任务创建时由内核分配的存储空间,会由空闲任务释放。 如果有应用程序调用xTaskDelete(),必须保证空闲任务获取一定的微控制器处理时间。...任务代码自己分配的内存是不会自动释放的,因此删除任务前,应该将这些内存释放。 7.2参数描述 「xTask」:被删除任务的句柄。为NULL表示删除当前任务。

    1.7K40

    Linux驱动开发-内核定时器

    内核定时器介绍 内核定时器是内核用来控制在未来某个时间点(基于jiffies(节拍总数))调度执行某个函数的一种机制,相关函数位于 和 kernel/timer.c 文件中...当内核定时器定时时间到达时,会进入用户指定的函数,相当于软中断。内核定时器注册开启后,运行一次就不会再运行(相当于自动注销),我们可以重新设置定时器的超时时间,让定时器重复运行。...内核每秒钟将jiffies变量增加HZ次。因此,对于HZ值为100的系统,jiffy+1等于隔了10ms,而对于HZ为1000的系统,jiffy+1仅为1ms。...如果编内核时不支持 SMP(多处理器), del_timer_sync()和 del_timer()等价 函数参数 timer:对应的定时器结构体 函数返回值 返回0:成功 函数定义文件 \linux-...= 12; /*传给定时器服务函数的参数*/ (3) 开启定时器。

    2.9K50

    听GPT 讲Rust源代码--srctools(12)

    这个错误在编译过程中经常会出现,表示函数调用时传递的参数数量与函数声明时的参数数量不匹配,可能导致函数无法正确执行。...该文件包含了一个名为MismatchedArgCountHandler的结构体,它是一个错误处理器,用于处理函数调用中参数数量不匹配的错误。...在MismatchedArgCountHandler中,实现了错误处理器的handle方法,用于处理函数调用时参数数量不匹配的错误,生成相应的错误信息和建议修复。...宏是 Rust 中的一种元编程工具,允许开发者通过编写宏来生成代码。当编译器遇到宏调用时,它会在编译之前将宏展开为实际的代码。...然后,它会检查宏调用节点的属性,并根据宏的定义规则,检查宏调用是否符合规范。如果宏调用存在问题,处理器会生成一条错误或警告的诊断消息,并存储到 diag (diagnostics) 数据结构中。

    19810
    领券