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

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

我们知道所有宏定义都将被重新扫描以查找更多要替换的宏,如果自引用被认为是宏的使用,它将产生无限大的扩展。 为防止这种情况,自引用不被视为宏调用。它原样传递到预处理器输出中。...实际上,每当在运行文本中使用预处理器时,预处理器都会将其单独保留。 如果宏x扩展为使用宏y,而y的扩展引用了宏x,则这是x的间接自引用。...参数预扫描处理 宏参数在被替换为宏主体之前必须经过完全宏扩展,替换后,将再次扫描整个宏主体,包括替换的参数,以查找要扩展的宏。...如果按照给定的方式替换了参数,并且没有进行预扫描,则剩余的单个扫描将找到相同的宏调用并产生相同的结果。 预扫描处理在以下三种特殊情况下有大的作用。...预扫描会导致发生预期的结果。 如果没有预扫描,f(1)本身将被替换为参数,并且f的内部使用将在主扫描期间作为间接自引用出现,并且不会扩展。

1.3K20

Android客户端性能异常类

超时 (Time Out) 没有在用户的预期内及时的响应用户的请求和交互。...被动类:在运行时执行一些指令或者访问某些内存地址被动触发的;不在预期范围内;比如:野指针,多线程操作文件没有同步保护等等。...常见问题有: 异常流程:当系统因内存不足无法分配buffer,代码就选择了调用宏函数,自杀了 虚拟内存泄漏:32位APP的地址空间只有4GB,因此程序运行过程中内存用的多了容易引起OOM。...线程挂起时间过长) local reference table overflow (本地引用表溢出) java.lang.OutOfMemoryError 文件描述符泄漏 堆内存破坏 SIGTKFLT 协处理器的栈异常...SIGTRAP SIGTRAP是通过汇编指令bkpt触发CPU的预取指异常,并在内核态的预取指异常处理函数中,给当前线程发送SIGTRAP信号。

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

    【嵌入式开发】ARM 异常向量表 ( 异常概念 | 异常处理流程 | 异常向量 | 汇编代码 )

    异常相关概念 (1) 异常 ---- 异常定义 : 1.异常简介 : 由于 内部或者外部的一些事件 , 导致 处理器停下正在处理的工作, 转而去处理这些发生的事; 2.处理器状态 : 当遇到异常的时候...程序被强行从一个固定的内存地址执行, 每个种类的异常都有对应的一固定内存地址, 这个内存地址就是异常向量 ; ---- (2) 异常类型简介 ---- 异常类型 : ARM 架构 支持 七种类型的异常, 1.Reset : 处理器在工作时..., 突然 按下重启键, 就会触发该异常; 2.Undefined instructions : 处理器无法识别指令的异常, 处理器执行的指令是有规范的, 如果 尝试执行 不符合要求的指令, 就会进入到该异常指令对应的地址中...; 3.Software interrupt (SWI) : 软中断, 软件中需要去打断处理器工作, 可以使用软中断来执行 ; 4.Prefetch Abort (instruction fetch...异常处理 (1) 异常处理 ---- 异常处理简介 : 1.异常向量工作机制 : 异常发生时, ARM 处理器会跳转到对应该异常的 固定地址 去执行异常处理程序, 这个 固定的地址 就是异常向量; 2

    3.7K10

    6小时完成芯片布局,谷歌用强化学习助力芯片设计

    策略和价值网络整体架构如上所示,其中嵌入层对网表邻接信息、节点特征和即将放置的当前宏的信息进行编码。然后,策略和价值网络分别输出可用布局位置的概率分布以及对当前布局预期奖励的估计。...比如,预训练策略有机地确定了一种布局:将宏放置在芯片的边缘附近,将标准单元放置在芯片中心的凸起空间。这将导致宏和标准单元之间的线长变短,不会带来过度的布线拥塞。...开源 RISC-V 处理器 Ariane 的宏布局随着训练进程的变化情况。左图中策略是从头开始训练的,而右图中使用预训练策略对芯片进行微调。每个矩形代表一个单独的宏布局。...注意,从头开始的策略发现的空洞在一开始就存在于预训练策略的布局中的。 研究者观察到预训练使得样本效率和布局质量均有所提升。...在此项研究工作中,研究团队始终是面向芯片布局这个核心点,此次提出基于强化学习的方法,而该方法也同时支持迁移学习,这表明强化学习的智能体会在越来越多的芯片网表中获得学习经验,从而在处理芯片布局方面变得更快更好

    77320

    《最新出炉》系列初窥篇-Python+Playwright自动化测试-4-playwright等待浅析

    而playwright为了避免我们犯这么low的错误,它对元素执行操作前,会进行一系列可操作性检查,以确保这些行动按预期运行。它会自动等待所有相关检查通过,然后才执行请求的操作。...翻译过来的大概意思就是说:自动等待:playwright对元素执行操作前,会进行一系列可操作性检查,以确保这些行动按预期运行。它会自动等待所有相关检查通过,然后才执行请求的操作。...如元素点击操作,在操作元素之前需要预判: 以下是针对每个操作执行的可操作性检查的完整列表: Action Attached Visible Stable Receives Events Enabled...''' Created on 2023-05-25 @author: 北京-宏哥 QQ交流群:705269076 公众号:北京宏哥 Project: 《《最新出炉》系列初窥篇-Python+Playwright...这是因为我们内部依赖于异步操作,并且在使用时time.sleep(5)无法正确处理它们。 4.1牛刀小试 宏哥就按照上边的方法实践一下。

    1.2K30

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

    引 什么是预处理器,跟我有什么关系? 预处理器是在OC源文件编译过程中的一个部分,而且是第一个处理部分,预处理器的预也由此可见。...整个编译过程可以大致分为:预处理器进行词法分析 -> 语法分析 -> 生成代码和优化 -> 生成可执行的二进制文件。 既然有这么多过程,为什么要关注预处理器呢?...除了上述的指令外,还有一个老熟人也属于预处理器的范畴,下文再来说。...预处理器之宏 要知道,宏也是预处理器范畴内的内容,我们用的也很多: // 定义常量值 #define 宏名 值 //定义函数宏 #define 宏名(参数) 代码 // 移除宏 #undef 宏名 宏被定义后...并不会 // 我们说了,宏只会简单替换,所以上面等价于: int number = 4 + 2 * 4 + 2;// 其实等于14 知道问题所在了吧,这很严重,因为不知道的话根本无法理解这个bug为什么会出现

    72330

    【C语言】深入解析assert 断言机制

    assert 是编写健壮代码的核心部分之一,它通过验证运行时假设的正确性,使得程序员在面对复杂系统时能够更高效地管理调试和测试工作。 C语言 什么是 assert?...值得注意的是,在软件开发中,逻辑错误通常是最棘手的问题之一,因为它们在编译阶段无法被检测到,而是在程序运行期间产生。...assert 的工作原理 assert 是一个宏,它依赖于预处理器的特性进行实现。...预处理器的作用 预处理器是 C 语言中在编译之前运行的一种工具,其主要作用是处理以 # 开头的指令,例如 #define 和 #include。...信息不可控: assert 的错误信息是固定格式的,无法提供足够的上下文。如果需要更详细的错误信息或用户友好的提示,开发者应手动编写类似的验证逻辑: if (!

    21210

    编译器内存屏障

    现代处理器采用标量体系结构和乱序执行 技术,能够在一个时钟周期内并发执行多条指令,处理器按照指令顺序取出,分析出没有依赖关系的指令然后发给多个处理器执行,最后按照顺序提交执行结果。...在有些情况下,处理器无法识别指令之间的关系,这时就会导致指乱序执行导致执行结果不符合预期 多CPU处理器系统中,有些程序设计者会使用存储缓冲区,引入处理器之间的内存访问乱系的问题,一个处理器修改了数据,...可能不会立即同步到自己的缓存或者其他处理器缓存,到时其他处理器不能立即看到最新的数据。...这里着重介绍编译器屏障 编译器屏障 为提高程序代码的执行效率,编译器对代码进行优化,对于不存在依赖关系的汇编指令,重新排列他们的顺序,但是编译器优化的结果不符合预期,开发者需要去控制或者阻止这种编译器优化...内核定义了宏READ_ONCE()、WRITE_ONCE()和ACCESS_ONCE()可以看做barrier()弱化形式,只阻止编译器对于单个变量优化,C语言提供了关键字volatile可以防止编译器优化单个变量

    53740

    基于DPDK(x86平台)应用性能优化实践

    可以在定义数据结构时用宏__rte_cache_aligned或加入padding成员。...一般访问CPU的cache效率最高,提前将需要处理的数据load到cache可以提高性能,但预取必须在合适的时间点发起,过早发起预取会导致数据还没有被使用就被替换出cache,最终适得其反,所以需要根据实际应用场景和多次尝试找到最合适的预取时间点...通常在进行数据包处理时会先对数据包进行预取操作。...通常作性能瓶颈分析时需要找一个软件基准版本,给出一个metric值(通常由测试仪器给出,比如时延、吞吐量),然后再通过分析工具定位出产生性能缺陷的代码,反复修改这部分代码再给出一个metric值与之间的值作比较,直到metric值达到自己的预期为止...6.jpg Bottom-up标签页按函数消耗CPU时间从大到小排序,并可以查看函数的调用栈,如果目标程序没有采用编译优化,VTune甚至能定位到具体代码行,通过这些信息就可以很容易找到哪些代码最消耗

    4.3K40

    C++内联函数

    一、内联函数概念 在c++中,预定义宏的概念是用内联函数来实现的,而内联函数本身也是一个真正的函数。 内联函数具有普通函数的所有行为。...唯一不同之处在于内联函数会在适当的地方像预定义宏 一样展开,所以不需要函数调用的开销。因此应该不使用宏,使用内联函数。 在普通函数(非成员函数)函数前面加上inline关键字使之成为内联函数。...这些事预 处理器无法完成的。 内联函数的确占用空间,但是内联函数相对于普通函数的优势只是省去了函数调用时候的压 栈,跳转,返回的开销。我们可以理解为内联函数是以空间换时间。...二、宏函数和内联函数区别 宏函数的替换是发生在预处理阶段 内联函数的替换是发生在编译阶段 宏函数容易出错,但是内联函数不会 我们希望的是 c = (10 +20 )* 5,但是用宏函数出现的却会为...类型检查和类型转换、包括在合适位置放入对象this指针这些都是预处理器不能完成的。

    1.2K40

    C语言:预处理详解

    使用举例: 1、利用#define定义宏求一个数的平方 #define SQUARE( x ) x * x 这个宏接收⼀个参数 x .如果在上述声明之后,你把 SQUARE( 5 ); 置于程序中,预处理器就会...⽤ 下⾯这个表达式替换上⾯的表达式: 5 * 5 观察第54行的语句,关于SQUARE(a+1),按道理应该打印36,为什么打印的时11??...吸取上次的经验,我们给宏定义的参数加上括号,因此我们会这样写 #define DOUBLE(x) (x) + (x) 这时又出现了问题,第62行代码按道理应该输出100,但是却输出了55。...我们发现替换之后: printf("%d\n", 10*(5)+(5)); 说明此时乘法运算优先于宏定义的加法,导致了计算不达预期。 要怎么解决呢??...这说明我们传入的参数产生了无法预料的结果! 结论:因为参数是完全不加替换带进去的,所以如果传入带有副作用的参数,可能会存在一些潜在的风险,无法预期后果,所以我们平时要尽量避免使用带有副作用的宏参数。

    35110

    【嵌入式开发】ARM 处理器工作模式 及 修改方法 ( 处理器模式 | 设置处理器模式 | 程序状态字寄存器 CPSR SPSR | 模式设置代码编写 | 设置 svc 模式 )

    ) 无法修改模式 : 在 用户模式 下, 应用也无法修改 处理器 的工作模式 ; ---- (3) Linux 系统运行的模式 ---- Linux 操作系统运行模式 : 1.应用程序 : Linux...和 读取数据失败 异常 ; 5.Undefined ( 未定义模式 und ) : 硬件协处理器 的 软件仿真支持, 当执行的指令处理器不支持, 那么会进入该模式, 对应异常类型 为 无法识别指令 异常...; 七种 异常类型 对应的 处理器工作模式 : ARM 架构 支持 七种类型的异常, 1.Reset : 处理器在工作时, 突然 按下重启键, 就会触发该异常 , 该异常对应的处理器工作模式为 svc...模式; 2.Undefined instructions : 处理器无法识别指令的异常, 处理器执行的指令是有规范的, 如果 尝试执行 不符合要求的指令, 就会进入到该异常指令对应的地址中, 该异常对应的处理器工作模式为...Abort (instruction fetch memory abort) : 预取指令失败, ARM 在执行指令的过程中, 要先去预取指令准备执行, 如果预取指令失败, 就会产生该异常, 该异常对应的处理器工作模式为

    3.2K40

    6小时完成,Jeff Dean领衔AI设计芯片方案登Nature,谷歌第四代TPU已用

    谷歌此前表示,TPUv4 可以在目标检测、图像分类、自然语言处理、机器翻译和推荐基准等工作负载上优于上一代 TPU 产品。...在电子设计自动化(EDA)出现之前,设计人员必须手工完成集成电路的设计、布线等工作,到了 1970 年代中期,开发人员尝试将整个设计过程自动化。...谷歌团队的系统从一个空芯片开始,按顺序放置组件,直到完成网表。为了指导系统选择先放置哪些组件,组件按大小递减进行排序,研究人员先放置大的组件,这样可以减少之后无法放置的可能性。...开源 RISC-V 处理器 Ariane 的宏布局随着训练进程的变化情况。左边:从头开始训练;右边:正在为这个芯片调整预训练策略。每个矩形代表一个单独的宏位置。...都对除目标块外的所有块预训练策略。

    40410

    我与C语言二周目邂逅vlog——7.预处理

    例如: #include #include #include "filename":用于引用用户自定义的头文件,通常从当前工作目录开始查找。...预处理的常见应用 6.1 代码的模块化和复用性 C语言预处理器通过文件包含(#include)使得代码可以按模块组织和复用。头文件用于声明函数、变量和数据结构,而源文件包含具体的实现。...预处理的局限性 虽然C语言的预处理非常强大,但它也存在一些局限性: 调试困难:由于预处理器只是进行文本替换,因此错误信息可能不太直观,宏展开后的代码难以调试。...预处理器在这一过程中充当“代码整理员”的角色,它确保代码在进入正式编译阶段之前符合预期。 编译过程可以划分为以下几个阶段: 预处理:处理宏定义、文件包含、条件编译等。...然而,由于预处理器的特性,它也带来了调试困难、类型不安全等问题。因此,在实际编程中,应该谨慎使用宏,多采用其他替代方案(如const、内联函数)来实现相同的功能。

    8810

    C语言预处理超详解

    使用举例: #define SQUARE( x ) x * x 这个宏接收一个参数 x.如果在上述声明之后,你把 SQUARE(5);置于程序中,预处理器就会用下面这个表达式替换上面的表达式:5 * 5...这个问题的解决办法是在宏定义表达式两边加上一对括号就可以了。 #define DOUBLE( x) ( ( x ) + ( x ) ) 这样就能得到预期的结果了。...注意: 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。 6....原因有二(和函数相比宏的优势): 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多(感兴趣可以自行了解:函数栈帧的创建和销毁)。...//注意:在 VS 等集成开发环境中这个代码是无法编译的!!

    10310

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

    但是应用层任务就不行了,它无法将处理器从低功耗模式唤醒,无法唤醒就无法运行!这个问题看来很棘手,既然应用层任务无法将处理器从低功耗模式唤醒,那么我们就借助其他的力量来完成这个功能。...() 使能 Tickless 模式以后当下面两种情况都出现的时候 FreeRTOS 内核就会调用宏portSUPPRESS_TICKS_AND_SLEEP()来处理低功耗相关的工作。...portSUPPRESS_TICKS_AND_SLEEP()应该是由用户根据自己所选择的平台来编写的,此宏会被空闲任务调用来完成具体的低功耗工作。但是!...如果使用 STM32 的话编写这个宏的工作就不用我们来完成了,因为 FreeRTOS 已经帮我们做好了,有没有瞬间觉得好幸福啊。...4、宏 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 处理器工作在低功耗模式的时间虽说没有任何限制,1 个时钟节拍也行,滴答定时器所能计时的最大值也行。

    3.8K30

    #pragma once和条件编译

    链接错误: 如果头文件中包含全局变量或函数定义,重复包含可能导致链接错误,因为链接器无法确定哪个定义是有效的。这种情况下,链接器可能会抛出多重定义的错误。...二、条件编译 #ifdef #ifdef 是 C 和 C++ 中的预处理器指令,用于条件编译。它用来检查是否已定义了某个标识符(通常是宏),如果已定义则执行一段代码,否则忽略这段代码。...编译器会按顺序检查每个条件,如果条件为真(即宏被定义),则执行相应的代码块,并跳过后续的条件。如果没有条件为真,则执行 #else 后面的代码块(如果存在)。...四、两者的区别 其实两者是差不多的,因为他两的工作原理其实是差不多的,但是值得注意的是在#ifndef结构中所定义的宏一般其实就是头文件的文件名全大写,那么如果在一个大型项目中,可能会出现两个名字相同但是内容不同的头文件...此外:虽然#pragma once 的工作原理类似于传统的头文件保护宏(例如 #ifndef、#define、#endif 结构),但是它是由编译器直接处理的,而不是由预处理器处理的。

    27410

    ZYNQ从放弃到入门(六)- 专用看门狗

    然而,在我们研究如何配置和使用 Zynq 看门狗之前,我认为最好先了解一下为什么需要看门狗定时器以及看门狗是如何工作的。看门狗解决了无响应软件的必然性,并为这个问题提供了可靠的解决方案。...这些故障可能会产生两种影响之一——允许软件继续运行,同时保持完整或减少的服务,或者完全无法响应。当软件无法响应时,看门狗定时器可以重新启动系统或确保系统安全的发生故障。...从最简单的意义上说,看门狗是一个从预加载值开始倒计时的计时器。当软件应用程序执行时,它会定期重置看门狗。如果软件未能重置看门狗,它的计数将达到零,然后看门狗电路复位处理器。...按下按钮启动私人(专用)定时器,点亮 LED,并启动看门狗。...我们可以使用读取看门狗复位状态寄存器的函数来查看最后一次复位是否是由于看门狗事件: XScuWdt_IsWdtExpired(InstancePtr) 下图显示了当处理器从上电复位和按下按钮以启用看门狗定时器时发生的复位上电时通过

    1.6K30

    程序环境和预处理

    如果在上述声明之后,你把 SQUARE( 5 ); 置于程序中,预处理器就会用下面这个表达式替换上面的表达式:(宏在预处理的时候,参数也会被替换) 5 * 5 警告: 这个宏存在一个问题:...在宏定义上加上两个括号,这个问题便轻松的解决了: #define SQUARE(x) (x) * (x) 这样预处理之后就产生了预期的效果: printf ("%d\n",(a + 1) * (...宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。 2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。...用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。 所以宏比函数在程序的规模和速度方面更胜一筹。  2. 更为重要的是函数的参数必须声明为特定的类型。...表达式的求值结果更容易预 测。 带 有 副 作 用 的 参 数 参数可能被替换到宏体中的多个位置,所以带有副作 用的参数求值可能会产生不可预料的结果。

    8410
    领券