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

在C++20中,如果一个宏是#undef的,那么它被认为是“活动的”,那么#define又被认为是“活动的”了吗?

在C++20中,宏的定义和取消定义的行为遵循预处理器规则。当使用 #define 指令定义一个宏时,该宏被视为“活动的”,即它在之后的代码中会被预处理器替换为其定义的值。相反,当使用 #undef 指令取消定义一个宏时,该宏不再被视为“活动的”,即它在之后的代码中不会被预处理器替换。

如果一个宏被 #undef 后,再次使用 #define 定义它,那么这个宏会重新变得“活动的”。这里的关键是理解宏的“活动状态”是根据其是否被定义来确定的。

例如:

代码语言:txt
复制
#define MACRO_NAME value

// MACRO_NAME 在这里是活动的,会被替换为 value

#undef MACRO_NAME

// MACRO_NAME 在这里不再是活动的,不会被替换

#define MACRO_NAME value

// MACRO_NAME 再次变得活动,会被替换为 value

在实际编程中,通常不建议频繁地定义和取消定义同一个宏,因为这可能会导致代码难以理解和维护。宏应该被谨慎使用,并且最好在文件的顶部或者配置头文件中定义。

如果你遇到了与宏定义相关的编译错误或者行为不符合预期,可能是因为宏在不应该被替换的地方被替换了,或者宏没有被正确地定义或取消定义。检查宏的定义和取消定义的位置,确保它们在正确的编译单元和作用域中被处理。

参考链接:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

断言assert()与调试帮助

列表内容assert()一种预处理(preprocessor marco),使用一个表达式来作为条件,只DEBUG模式下才有用。...assert行为依赖与NDEBUG预处理变量状态,如果定义了这个变量,则assert什么也不做。...如果定义了NDEBUG,编译器会认为是非DEBUG模式(like release模式) #include #include // 去注释则禁用 assert() //...这里有一个问题,如果这么写,将定义写在头文件之后的话,那么这个禁用将不起效果,这里assert()仍然会执行。...而如果在这个之后定义了NDEBUG,也就相当于在上面最后又加了一句#define NDEBUG,但是这个时候检查已经开始了,所以这一句也没用了。 辅助诊断变量,均在预处理器定义.

64130
  • 预处理

    #endif 它作用是:如果(MAX==10)||(MAX==20)成立,那么编译器就会把其中#if 与 #endif之间代码编译进去(注意:编译进去,不是执行!!)...#if defined使用 #if后面接一个。 #if defined (x) ...code......#endif 这个#if defined它不管里面的“x”逻辑“真”还是“假”它只管这个程序前面的定义里面有没有定义“x”这个如果定义了x这个那么,编译器会编译中间…code…否则不直接忽视中间...error C2065: 'CONST_NAME1' : undeclared identifier 表示当前文件名称被认为是Hello.c, #line 10 "Hello.c"所在下一行被认为是第...常用于链接一个动态库,如 #pragma comment(lib, "user32.lib"); 也有linker:将一个链接选项放入目标文件,你可以使用这个指令来代替由命令行传入或者开发环境设置链接选项来强制包含某个对象

    1.1K30

    【为正名】本应写入教科书“世界设定”

    #endif 其次,定义时候,如果只给了名字却没有提供内容: #ifdef、#ifndef 以及 defined() 表达式,它可以正确返回boolean量——确切表示它被定义了; #if...,如果要用到胶水运算,一定要在内部借助参数来完成粘合过程 为了理解这一“结论”,我们不妨举一个例子:在前面的代码,我们定义过一个用于自动关闭中断并在完成指定操作后自动恢复原来状态: #define...【引用而非变量】 ---- 具体实践,很多人在使用过程中会产生“一种变量”错觉,这是因为无论一个此前是否定义过,我们都可以借助 #undef 操作,强制注销它,从而有能力重新给这一赋予一个值...: CONNECT2(uint32_t wVariable, EXAMPLE); 如果一个变量,那么展开结果应该是: uint32_t wVariable123; 然而,我们实际获得: uint32...如果一个引用,那么当EXAMPLE_A与123之间关系被销毁时,原本EXAMPLE > EXAMPLE_A > 123 引用关系就只剩下 EXAMPLE > EXAMPLE_A。

    76740

    【C语言】预处理

    被替换成了1000; 1000;不能通过printf打印 所以我们得出一个结论:使用#define定义数字时,尽量不要加入符号 三、#define定义 #define机制包括了一个机制,就是允许把参数替换到文本...name与旁边参数列表左圆括号必须紧邻,如果二者之间有任何空白存在,参数列表就会被认为是stuff一部分 举一个求平方例子: #define SQUARE( x ) x * x 当我们使用SQUARE...,看看它是否包含任何由#define定义符号,如果,就重复上述处理过程,也就是再次扫描然后重复上述过程 4、参数和#define定义可以出现其他#define定义符号,但是不能够递归...,使用函数会更有优势一些 1、每次使用时候,定义代码会插入到程序较长情况下可能会导致大幅度增加程序长度 2、无法调试 3、与类型无关,这虽然一个优点,也是一个缺点,因为这导致它不够严谨...,然后其他代码使用小写,这样可以很好区分、函数以及其他代码 九、#undef #undef 可以移除一个定义,如果现存一个名字需要被重新定义,那么就使用它进行移除 #undef NAME 十、命令行定义

    10810

    从php内核角度分析php弱类型

    ,PHP定义了大量,供我们检测、操作变量使用 解释下什么 C语言中允许用一个标识符来标识一个字符串,称为“”;标识符为“名”。...一般形式:#define 名 字符串 定义说明及注意: 定义时用名来表示一个字符串,展开时又以该字符串替换了名,这只是一个简单替换; 定义不需要再行末加分号,若加上分号,则会连分号也会被替换...; 定义必须在函数外面;定义作用域:从定义命令至程序结束,若想终止作用域,则使用undef命令; 程序中用引号括起来,则预处理程序对其不进行替换; 定义可以嵌套使用展开时,由预处理程序层层替换...经过查询我们可以知道这句话来源于 #define Z_ISREF(zval) (Z_TYPE(zval) == IS_REFERENCE) 其意思为 该zval检查它是否一个引用类型,姑且认为是判断这个变量是否属于...如果没有,那么一个哈希表被认为更大, 看到这里大家疑惑都解决了吧 后记 通过这次探寻,我深刻发现到往往很多我们认为是常识东西都有着很多极其复杂原理,我们认识一件事物时候不能仅仅只凭借表面现象就根据自己直觉来得出结论

    1.8K20

    【为正名】99%的人从第一天学习C语言就自废武功

    【未曾设想道路】 ---- 一般情况下,我们创建头文件都可以被归入“不可重入”大类,顾名思义,就是如果这个头文件被同一个 C 源文件直接或间接包含(include)了多次,那么就会出现“内容重复定义...一个用于表示序号,初值0 #define MY_INDEX 0 每次使用下面的预编译代码,我们就可以实现将 MY_INDEX值加一效果: //!...0~255初始值); 为同样模板提供不同解释 第一个大类,我们已经文章【为正名】什么?...理想如果一个可重入头文件 mf_u8_fill_dec.h,它接受三个作为输入参数: MFUNC_IN_START——起始数字 MFUNC_IN_DELTA——间隔 MFUNC_IN_COUNT...这里技巧,将循环体放置递归调用后面,换句话说:我们做法先一口气积攒足够递归深度,然后逐层返回过程执行循环体。

    68931

    (预编译)详解

    申明方式:#define name(parament-list) stuff , 其中parament-list一个由逗号隔开符号表,他们可能出现在stuff。...3.2.3#define替换规则 程序扩展#define定义符号和时, 需要涉及这几个步骤: 1.调用时,首先对参数进行检查,看看是否包含任何由#define定义符号,如果,他们首先被替换...The value c is...这样类似的输出如果用printf函数,少量字符串CV一下就行,但是 如果需要特别多行类似的语句printf函数做不到那么做不做得到呢?...实质上这个其实是PRINT(n) printf("The value ""n"" is %d\n",n),相当于'#'后面部分字符串改变后又被重新拼接起来形成一个完整字符串。...3.3条件编译 在编译一条语句时候我们如果要将一条语句(一组语句)编译或者放弃很方便。因为我们有条件编译指令。 那么条件编译指令有哪些?

    21910

    【C语言】定义

    #define Num 1000         说明:上述代码作用就是该程序中用Mum来替代1000,在编译预处理时候,每当代码源程序遇到Mum就自动用1000来进行代替。         ...使用函数时候我们需要注意它数据类型,但是当中我们不需要注意,想整形就是整形想浮点型就是浮点型。说明用在这里更加灵活只是处理简单问题上切记。...那么我们平时写或者函数时候习惯明全部大写形式。 函数明不要全部大写,建议第一个字母大写。...✔拓展⇢用do...while(0)语句结构可以插入多条语句结构因为有花括号{}。 #undef #undef 为取消定义,用于移除一个定义。...格式形式如下 #undef NAME 如果现在一共名字需要被重新定义的话,那么旧名字就会被移除。

    32510

    【c语言】你绝对没见过预处理技巧

    前言 c语言中,预处理(预编译)整个程序流程很重要一个环节。本篇文章我们主要介绍一些关于c语言中预处理相关知识以及指令。...它语法格式: #define name( parament-list ) stuff 其中,name名,括号内容参数(一个或多个(由逗号隔开)符号表),这些符号可以出现在之后...这里需要注意两点: 1.参数和#define定义可以出现其他#define定义符号。...##操作符 ##操作符又被称为记号粘合操作符,它可以将我们传入参数与其他字符粘合起来,成为一个合法标识符。 比如我们现在想要实现求两个变量最大值。...而这里##操作符就通过传入类型产生了不同函数名。 六、#undef #undef用于撤销一个定义。

    13610

    Verilog HDL仿真常用命令

    例如:`timescale 1ns / 1ns 时间单位定义仿真时间和延迟时间基准单位;时间精度定义模块仿真时间精确程度又被称为取整精度(仿真前,被用来对延迟时间值进行取整操作)。...如果在同一个设计,出现多个`timescale命令,工具会采用最小时间精度值来决定仿真的时间单位。...定义`define 设计,为了提高程序可读性和简化程序描述,可以使用指定标识符来代替一个字符串,或者使用一个简单名字来代替没有含义数字或者符号,此时需使用到定义命令`define。...其一般形式为: ``include “文件名”` 例:文件para.v中有一个定义 `define A 2+3, test.v文件可以直接调用。...包含文件2,而文件2要用到文件3内容,那么文 例:para.v : `define A 2+3 para2.v : `define B `A+2 test.v: `timescale 1ns

    91140

    朴素、Select、Poll和Epoll网络编程模型实现和分析——Select模型

    《朴素、Select、Poll和Epoll网络编程模型实现和分析——朴素模型》我们分析了朴素模型一个缺陷——一次只能处理一个连接。...我们使用一个for循环遍历每个socket。如果该socket通过FD_ISSET判断不处于我们关注可读事件fd_set,则忽略它。        ...还要使用FD_SET将该socket加入到活动状态fd_set。之后该活动状态fd_set将被赋值给需要关注可读事件fd_set。        ...代码似乎没有任何让它们产生关联逻辑,而且它们关系严格“相等”关系!那么只有一个假设,就是make_socket和accept返回socket值FD_SETSIZE和0之间。...__FDS_BITS定义fd_set定义

    79120

    预处理命令

    与typedef作用域区别: typedef: 如果放在所有函数之外,它作用域就是从它定义开始直到文件尾 如果放在某个函数内,它作用域就是从它定义开始直到该函数结尾 #define: 不管某个函数内...叫定义,但是笔者认识里对声明和定义理解:声明不分配内存,定义才分配内存,所以#define虽然名字里面有“定义”两个字,但并不占存储空间(为什么不叫声明···) 总结:#define和声明、...定义都不同,定义不占内存空间,因为预处理阶段就会被替换掉,到了编译阶段没有存在,它在预编译阶段就被处理了 #undef 上文提到#define作用域从它声明开始到文件结尾,#undef...就是取消之前定义(也就是#define标识符) 格式:#undef 标识符(注意:如果标识符当前没有被定义成一个名称,那么就会忽略该指令) 1 #include 2...#if命令要求判断条件为整型常量表达式,也就是说表达式不能包含变量,而且结果必须整数;而if后面的表达式没有限制,只要符合语法就行,这是#if和if一个重要区别 #ifdef #ifdef作用是判断某个是否定义

    80331

    编译预处理

    = %d\nS = %d\n",L,W,S); } 如果没有括号那么S将会被替换成80+40*80 很明显不对,所以需要用圆括号 另外在printf内,双引号LWS没有被替换,仅替换不在双引号以内...而替换在编译时进行,仅仅进行替换 例如:#define sqr(x) (x)*(x) 调用时有y=sqr(a+b);展开时候,直接用a+b替换x值,函数形参和实参要求类型兼容,而定义只是进行符号替换...函数调用占用程序运行时间,展开占用编译时间 参数和名之间没有空格,如果有空格,名会被定义为一个符号常量 如果展开后根据优先级可能会有误解,则需要在定义时候加上圆括号 解除定义 接触定义 作用...:限定定义作用域一个范围内,可以用\#undef 命令来解除已有的定义 格式:#undef 名 \#define MAX 100 ......\#undef MAX 使得MAXundef之前有效,之后便不再有效 重新定义 undef一个作用是重新进行定义,C语言中不能重复定义,即程序不能使用同名

    18610

    【C++】const 关键字 与 #define 定义 对比 ( 相同点 - 都可定义常量和优化性能 | 不同点 - const 常量进行作用域检查和类型检查 )

    一、const 关键字 与 #define 定义 相同点 C++ , const 可以作为 替代 #define 定义 手段 ; const 常量定义 : const int a = 10..., 存储只读存储区 , 即 符号表 ; #define 定义 定义 常量 , 预编译时也可以进行优化 , 如 内联展开 ; 2、代码示例 - 变量作为数组大小报错 C 语言中 , 定义数组...define 定义 预处理器 预处理阶段 进行处理 , 不会进行 类型检查 和 作用域检查 , 只是进行单纯 文本替换 ; 在下面的代码 , 只要调用了 fun1 函数 , 执行了 #define...a 10 代码 , 那么在后续不管哪个函数 , 都可以调用 a 定义值 ; 但是 fun1 函数 定义了 常量 b , 代码为 const int b = 20; , 只能在 fun1 函数调用该常量...标准做法 , 函数中使用了 定义 a , 如果在函数结尾不再使用该 定义 , 那么可以卸载该定义 , 使用 #undef a 可卸载定义 , 使用 #undef 可卸载所有定义 ; void

    40740

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

    那么n就是5,type就是int,也就是有一个参数类型,可以实现,但函数可以实现,预处理之后替换结果就是(int*)malloc(5 * sizeof(int))。...那我们平时⼀个习惯: 把名全部大写 函数名不要全部大写 三、#undef #undef一个预处理器指令,用于取消已经定义。...#undef 指令通常用于以下情况: 防止名冲突:如果在不同头文件定义了相同名,或者修改代码时需要改变定义,可以使用 #undef 来确保最新定义有效。...条件编译:条件编译块,可能需要根据某些条件取消定义,这时可以使用 #undef。 清理定义:某些复杂定义,可能需要在展开后清理定义,以防止名被错误地使用。...,那么test.h文件内容将会被拷贝5份test.c

    15210

    C语言中定义

    这些参数可以替换列表根据需要出现任意次。 名字和左括号之间必须没有空格。如果有空格,预处理器会认为是定义一个简单,其中(x1,x2,…,xn)替换列表一部分。...4) 、不可以被定义两遍,除非新定义与旧定义一样。小间隔上差异允许,但是替换列表(和参数,如果有的话)记号都必须一致。 5) 、可以使用#undef指令“取消定义”。...#undef指令有如下形式: [#undef指令]  #undef 标识符 其中标识符一个名。例如,指令 #undef N 会删除N当前定义。...(如果N没有被定义成一个,#undef指令没有任何作用。)#undef指令一个用途取消一个现有定义,以便于重新给出新定义。 6....对于一个定义哪里要加圆括号有两条规则要遵守: 首先,如果替换列表中有运算符,那么始终要将替换列表放在括号: #define TWO_PI (2*3.14159) 其次,如果有参数,

    6.4K10

    提高代码逼格利器:定义-从入门到放弃

    我们可以认为是编译目标平台(操作系统)为我们预先准备好。...#define TRUE #endif #ifndef FALSE #define FALSE #endif 在数据类型定义,需要注意一点如果程序需要用不同平台下编译器来编译...; 如果一个多处调用,会增加代码体积; 还是举一个例子来说明比较好,就拿上面的比较大小来说吧: (1) 使用来实现 #define MAX(a, b) (((a) > (b)) ?...如果使用三个点(...)来接收可变参数,那么使用时候就需要使用 __VA_ARGS__ 来表示可变参数,如下: #define debug1(...)...日志功能 代码添加日志功能,几乎每个产品标配了,一般见到最普遍下面这样用法: #ifdef DEBUG #define LOG(...) printf(__VA_ARGS__) #

    1.1K40

    sar(1) command

    1.简介 sar(System Activity Report)收集、报告或保存系统活动信息。 sar 一个用于监控和报告系统性能命令行工具。...filename 参数默认值当前标准系统活动每日数据文件。如果 filename 一个目录而不是一个普通文件,那么它被认为是标准系统活动日常数据文件所在目录。选项 -f 与 -o 互斥。...-o [ FILENAME ] 将读数以二进制形式保存在文件。每个读数都在一个单独记录。filename 参数默认值当前标准系统活动每日数据文件。...如果 filename 一个目录而不是一个普通文件,那么它被认为是标准系统活动日常数据文件所在目录。 选项 -0 与 -f 互斥。...每 2 秒报告一次 irq14 统计信息。总共进行 10 次采样。数据存储名为 int14.file 文件

    10710

    xmake v2.5.9 发布,改进 C++20 模块,并支持 Nim, Keil MDK 和 Unity Build

    而通过 Unity Build,我们通过将多个 cpp 文件组合成一个来加速项目的编译,其主要好处减少了解析和编译包含在多个源文件头文件内容重复工作,头文件内容通常占预处理后源文件大部分代码...另外在 Unity Build 模式下,我们还是可以做到尽可能并行编译加速,互不冲突。 如果没有设置 batchsize 参数,那么默认会吧所有文件合并到一个文件中进行编译。...foo 和 bar 定义完全不同,可以按文件名算一个唯一 ID 值出来,互不冲突,也就是实现下面的合并效果: #define MY_UNITY_ID #include..."foo.c" #undef MY_UNITY_ID #define MY_UNITY_ID #include "bar.c" #undef MY_UNITY_ID...如果用户额外安装了 gcc-11, gcc-10 等特定版本 gcc 工具链,本地 gcc 程序命名可能 /usr/bin/gcc-11。

    2.5K10
    领券