c - 双哈希使用
问题描述
在 C99 6.10.3.3.(2) 中(我的亮点)
如果在类函数宏的替换列表中,参数紧跟在## 预处理标记之前或之后,则将参数替换为相应参数的预处理标记序列;但是,如果参数不包含预处理标记,则该参数将替换为地标预处理标记。
#include <stdio.h>
#define hash_hash(a, b) a ## b
#define mkstr(a) # a
#define in_between(a) mkstr(a)
void main(void)
{
char p[] = in_between(a hash_hash(,) b);
printf("%s", p);
}
输出:
a b
我描述了突出显示的短语hash_hash(,)
,结果似乎作为标准的表示是正确的。
但是我想知道是否省略了逗号,
,例如hash_hash()
,那么这与标准的解释(未定义的行为)有什么不同?和placemaker
空白一样吗?
解决方案
,
如果省略逗号,例如hash_hash()
,那么这与标准的解释不同(未定义的行为)吗?placemaker 和 white-space 一样吗?
是的,如果使用参数定义宏,则参数必须用逗号分隔符分隔。否则尝试定义多参数宏将违反标准规则,并且无法编译:
类函数宏可以接受参数,就像真正的函数一样。要定义使用参数的宏,请在宏定义中的括号对之间插入参数,使宏具有类似函数的功能。参数必须是有效的 C 标识符, 以逗号和可选的空格分隔。
此外,
- 由于此要求已明确定义,因此它不会是未定义行为的示例。
- 在参考段落的这个短语和 可选的空格中,and表示空格可以与分隔符一起使用,但其本身不足以作为分隔符。
推荐阅读
- javascript - Firebase云功能:从文档创建中执行查询,然后删除除新创建的结果之外的结果
- python - TypeError:迭代 0-d 张量
- spring - SessionCreationPolicy.STATELESS 时显示 spring 安全认证对象
- flutter - 等效于 Riverpod 中的 ChangeNotifierProvider 小部件
- mysql - 字符串部分搜索
- gnuplot - Inkscape 裁剪使用 gnuplot 生成的 eps 文件
- nix - Nix:将其他派生的子目录添加到 PATH
- c - 是否存在可移植的 pthread_sleep() 函数?
- r - 如何执行模拟以在 R 中找到具有给定概率的 z 分数 (x)
- angular - 如何在 Angular/RxJS 中合并两个 observable?