Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >生锈宏:带括号的宏体和带括号的宏体有什么区别?

生锈宏:带括号的宏体和带括号的宏体有什么区别?
EN

Stack Overflow用户
提问于 2020-05-23 00:45:03
回答 2查看 903关注 0票数 0

阿法克,Rust中的宏由以下语法声明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
macro_rules! <name> {
    (<pattern>) => {
        <implementation>
    };
}

但是,我发现了一个版本,在这个版本中,主体是用括号括起来的,而不是生锈中的大括号。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
macro_rules! <name> {
    (<pattern>) => (
        <implementation>
    )
}

还请注意丢失的尾随分号。我最好的猜测是,这与这个宏使用的尾递归有关,但是,在括号中的宏体和用大括号括起来的宏体之间的官方区别是什么呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-23 01:10:06

macro_rules中的分支只需用;分隔。尾随分号在那里是可选的。在形式语法 of macro_rules中,这是由

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MacroRules :
   MacroRule ( ; MacroRule )* ;?

这里的语法类似于regex。规则列表至少是一个规则,后面是任意数量的分号-MacroRule对。所有这些后面都是一个可选的分号。

在这里,选择(){}还是[]实际上并不重要。这三种方法都是解析DelimTokenTree的公认方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
DelimTokenTree :
     ( TokenTree* )
   | [ TokenTree* ]
   | { TokenTree* }

这意味着无论DelimTokenTree是由()[]还是{}包围的,它都将被解析为相同的内容。

特别是,您所链接的宏与选择括号和尾随分号的所有六个组合一样工作。

票数 2
EN

Stack Overflow用户

发布于 2020-05-23 01:02:05

(..)[..]{..}之间的宏定义没有区别,参见参考文献=>右侧的块的语法是DelimTokenTree。我想,拥有这三个变体的动机是允许宏的模式包含任意两种类型的大括号。

分号是可选的,在MacroRules语法中可以看到。您甚至可以对宏的外部部分使用(..)[..]

当您使用调用宏时,您也可以使用这三种口味,但是如何使用这三种口味都有限制:

当用作项或语句时,如果不使用大括号,则在末尾需要分号的情况下使用MacroInvocationSemi窗体。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61969531

复制
相关文章
c语言之带参数的宏定义
2.在带参数的宏定义中,形参参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体值,要用它去代换形参,因此必须作类型说明。
西西嘛呦
2020/08/26
2.5K0
c语言之带参数的宏定义
1179: 带参宏定义(函数专题)
从键盘输入三个字符,用空格隔开,使用带参宏定义1中SWAP,将三个字符按从大到小的顺序排序输出。 宏定义1:#define SWAP(a, b, t) { t=a; a=b; b=t; } 请尝试,如果用宏定义2中的SWAP,主函数需要如何修改才能得到正确结果? 宏定义2:#define SWAP(a, b, t) t=a; a=b; b=t;
怠惰的未禾
2023/04/27
2850
使用宏初始化结构体
今天代码评审看到使用宏来初始化结构体的操作。   代码大致如下,你们觉得如何呢? #include <stdio.h> #define CAR(weight, width, height) { weight, width, height } typedef struct Car { int weight; int width; int height; } Car; int main(int, char **) { Car car = CAR(100, 20, 10);
Qt君
2023/03/17
3730
使用宏初始化结构体
C语言知识总结——宏,枚举,结构体,共用体
以#号开头的都是编译预处理指令,它们不是C语言的成分,但是C程序离不开它们,#define用来定义一个宏,程序在预处理阶段将用define定义的来内容进行了替换。因此在程序运行时,常量表中并没有用define定义的常量,系统不为它分配内存。define定义的常量,预处理时只是直接进行了替换,,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。,因此在编译时它不对宏的定义进行检查,作用域不影响对常量的访问 。它的常量值只能是字符串或数字。 该命令有两种格式:一种是简单的常量宏定义, 另一种是带参数的宏定义。
C语言与CPP编程
2021/04/30
2.4K0
【C语言笔记】带参宏定义(一)
公司某项目用到DSP+FPGA架构(当然不是著名的ARM+DSP+FPGA点灯项目,哈哈),我的发展方向为DSP方向。其中DSP与FPGA通过两个带参宏进行数据交互(DSP与FPGA通过一块共享内存来实现数据交互,我这边的DSP只要往共享内存中写入数据即为往FPGA中写数据,往共享内存中读取数据就是读取FPGA发送过来的数据),如下图:
正念君
2019/06/26
1.3K0
【C语言笔记】带参宏定义(一)
【C语言笔记】带参宏定义(二)
其中参数列表中的参数之间用逗号分隔,字符序列中应包含参数表中的参数。在定义带参数的宏时,宏名标识符与左圆括号之间不允许有空白符,应紧接在一起,否则变成了无参数的宏定义。
正念君
2019/06/26
3K0
【C语言笔记】带参宏定义(二)
Python中类-带括号与不带括号的区别
  有时候看到群里一些人问一些基础的知识,虽然很基础,网上随便一查即可知道,但是往往很多人就是连这些基础的知识都很模糊,甚至不清楚,这里再来复习一下python中类的一个知识点(仅此)。
全栈测试开发日记
2023/02/02
2.6K0
C语言宏定义、共用体、枚举类型
宏定义 在c语言程序编译之前处理的内容。 一般形式:#define 标识符 字符串 宏定义 文件包含 条件编译 1.不带参数的宏定义。 例:输入圆的半径,求圆的周长(2*pi*r)和面积(pi*r*r). #include<stdio.h> #define PI 3.14159 int main(){ float r; scanf("%f",&r); float s=PI*r*r; printf("S=%-10.3f\n",s); float c=PI*2*r;
岳泽以
2022/10/26
6910
C语言宏定义、共用体、枚举类型
#ifdef宏名和#ifndef宏名
#ifdef宏名: #include<iostream> #include<conio.h> using namespace std; #define dhy //定义宏名 int main() { #ifdef dhy //如果宏名定义了执行ifdef代码 cout << "你好,世界" << endl; #else //未定义宏名则会执行else后面的代码 cout << "再见,世界" << endl; #endif //dhy _getch(); return 0; } #ifndef
大忽悠爱学习
2021/02/22
7810
C语言带参数的宏定义:#define f(X) ((X)*(X))
在以上知识点总结7里面,有很多同学对宏定义的理解还不是很透彻,今天以一个例题深入分析一下。没复习到的同学可以查看上面链接先熟悉一下。
用户6755376
2020/02/20
5.3K0
C语言带参数的宏定义:#define f(X)  ((X)*(X))
Java中的宏变量,宏替换详解。
群友在微信群讨论的一个话题,有点意思,特拿出来分享一下。 输出true false 来看下面这段程序,和群友分享的大致一样。 public static void main(String[] args
Java技术栈
2018/03/30
3.8K0
Java中的宏变量,宏替换详解。
2022-11-14:rust语言,请使用过程宏给结构体AAA生成结构体AAABuilder和创建AAABuilder实例的方法。 宏使用如下: #[deriv
2022-11-14:rust语言,请使用过程宏给结构体AAA生成结构体AAABuilder和创建AAABuilder实例的方法。
福大大架构师每日一题
2022/11/14
4180
2022-11-14:rust语言,请使用过程宏给结构体AAA生成结构体AAABuilder和创建AAABuilder实例的方法。 宏使用如下: #[deriv
C语言 | offsetof宏和container_of宏
今天分享C语言中的两个宏,这两个宏包含了指针和结构体的知识,非常具有代表性。另外,这个题目曾经是大疆无人机的一道笔试题,可见,这两个宏对C语言基础还是有一定要求的。先说明一下,今天所有的例子都是以32位系统来说的。
飞哥
2020/07/10
2.2K0
C语言 | offsetof宏和container_of宏
宏中"#"和"##"的用法
一、一般用法  我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.   用法:   #include<cstdio>   #include<climits>   using namespace std;   #define STR(s) #s   #define CONS(a,b) int(a##e##b)   int main()   {     printf(STR(vck)); // 输出字符串"vck"     printf("%d   ", CONS(2,3)); // 2e3 输出:2000     return 0;   }   二、当宏参数是另一个宏的时候  需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.   1, 非'#'和'##'的情况   #define TOW (2)   #define MUL(a,b) (a*b)   printf("%d*%d=%d   ", TOW, TOW, MUL(TOW,TOW));   这行的宏会被展开为:   printf("%d*%d=%d   ", (2), (2), ((2)*(2)));   MUL里的参数TOW会被展开为(2).   2, 当有'#'或'##'的时候   #define A (2)   #define STR(s) #s   #define CONS(a,b) int(a##e##b)   printf("int max: %s   ", STR(INT_MAX)); // INT_MAX #include<climits>   这行会被展开为:   printf("int max: %s   ", "INT_MAX");   printf("%s   ", CONS(A, A)); // compile error    这一行则是:   printf("%s   ", int(AeA));   INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏.   加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.   #define A (2)   #define _STR(s) #s   #define STR(s) _STR(s) // 转换宏   #define _CONS(a,b) int(a##e##b)   #define CONS(a,b) _CONS(a,b) // 转换宏   printf("int max: %s   ", STR(INT_MAX)); // INT_MAX,int型的最大值,为一个变量 #include<climits>   输出为: int max: 0x7fffffff   STR(INT_MAX) --> _STR(0x7fffffff) 然后再转换成字符串;   printf("%d   ", CONS(A, A));   输出为:200   CONS(A, A) --> _CONS((2), (2)) --> int((2)e(2))   三、'#'和'##'的一些应用特例  1、合并匿名变量名   #define ___ANONYMOUS1(type, var, line) type var##line   #define __ANONYMOUS0(type, line) ___ANONYMOUS1(type, _anonymous, line)   #define ANONYMOUS(type) __ANONYMOUS0(type, __LINE__)   例:ANONYMOUS(static int); 即: static int _anonymous70; 70表示该行行号;   第一层:ANONYMOUS(static int); --> __ANONYMOUS0(static int, __LINE__);   第二层: --> ___ANONYMOUS1(static int, _anonymous, 70);   第三层: --> static int _anonymous70;   即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开;   2、填充结构   #define FILL(a) {a, #a}   enum IDD{OPEN, CLOSE};   typedef struct MSG{     IDD id;     const char * msg;   }MSG;   MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};   相当于:   MSG _msg[] = {{OPEN, "OPEN"},     {CLOSE, "CLOSE"}};   3、记录文件名
阳光岛主
2019/02/20
1.2K0
C语言有参数宏定义与无参数宏定义
前两天上课,被JAVA老师问懵了,老师问:“你们学C语言,有没有写过带参的宏玩一玩”,说实话,我根本没听过什么带参的宏,我只用过宏定义,所以我下来一定要找个时间把这“带参的宏搞懂”,于是就有了这篇文章。        C语言中宏定义分两种,无参的宏和有参的宏 1.无参数的宏        无参数宏定义的一般形式为: #define name value//name是你起的名字,就跟起函数名一样,value是你要给这个名字赋予什么值 //示例: #include <iostream> using name
mathor
2018/06/22
3K0
Excel宏教程 (宏的介绍与基本使用)
大家好,又见面了,我是你们的朋友全栈君。 Excel宏教程 (宏的介绍与基本使用) Microsoft excel是一款功能非常强大的电子表格软件。它可以轻松地完成数据的各类数学运算,并用各种二维或三维图形形象地表示出来,从而大大简化了数据的处理工作。但若仅利用excel的常用功能来处理较复杂的数据,可能仍需进行大量的人工操作。但excel的强大远远超过人们的想象–宏的引入使其具有了无限的扩展性,因而可以很好地解决复杂数据的处理问题。 随着支持Windows的应用程序的不断增多和功能的不断增强,越来
全栈程序员站长
2022/08/23
6.5K0
DragonOS中的READ_ONCE()宏和WRITE_ONCE()宏
DragonOS中实现了与Linux相似的READ_ONCE()宏以及WRITE_ONCE()宏,主要目的在于解决并行计算场景下,编译器错误的优化导致的数据访问错误的问题。下面进行简单的介绍:
灯珑LoGin
2022/10/31
7160
excel批量导入图片 宏_怎么启用excel的宏
  图片格式规范:C盘的picture文件夹,放100张有序命名的图片,即1.jpg,2.jpg,3.jpg…100.jpg
全栈程序员站长
2022/09/21
2.1K0
excel批量导入图片 宏_怎么启用excel的宏
gtest宏列表_指定宏怎么用
总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:
全栈程序员站长
2022/11/10
1.1K0
container_of宏定义作用_宏内核
上一篇我们讲到内核链表和普通链表的区别,就有小伙伴追问:内核链表是怎么通过指针域来访问数据域的呢?这篇文章我们就来解答这个问题。
全栈程序员站长
2022/09/23
1.3K0

相似问题

带_Pragma括号的宏

10

带--删除-括号和宏的样式

28

带零参数的宏-带括号或不带括号

30

如何删除带宏的括号?

45

具有带括号的结构的宏

22
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文