c++ - 为什么我需要宏的双层间接?

标签 c++ visual-c++ macros

在:C++ FAQ - Miscellaneous technical issues - [39.6] What should be done with macros that need to paste two tokens together?

谁能解释一下为什么?我读到的只是相信我,但我不能仅仅因为有人这么说就相信某事。

我尝试了该方法,但找不到任何出现的错误:

#define mymacro(a) int a ## __LINE__
mymacro(prefix) = 5;
mymacro(__LINE__) = 5;
int test = prefix__LINE__*__LINE____LINE__; // fine

那么为什么我需要这样做(引自网页):

However you need a double layer of indirection when you use ##. Basically you need to create a special macro for "token pasting" such as:

 #define NAME2(a,b)         NAME2_HIDDEN(a,b)
 #define NAME2_HIDDEN(a,b)  a ## b 

Trust me on this — you really need to do this! (And please nobody write me saying it sometimes works without the second layer of indirection. Try concatenating a symbol with __ LINE__ and see what happens then.)

编辑: 有人能解释一下为什么他在下面声明之前使用 NAME2_HIDDEN 吗?在我使用它之前定义 NAME2_HIDDEN 宏似乎更合乎逻辑。这是什么诡计吗?

最佳答案

C 规范的相关部分:

6.10.3.1 Argument substitution

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

决定是否要双重间接寻址的关键部分是第二句和其中的异常——如果参数涉及到### 操作(例如 mymacroNAME2_HIDDEN 中的参数),则在执行 # 之前不会扩展参数中的任何其他宏或 ##。另一方面,如果宏体中没有 ### 立即(与 NAME2 一样),那么在参数已扩展。

所以这取决于你想要什么 - 有时你希望首先扩展所有宏,然后执行 ### (在这种情况下,你想要双层间接),有时你不希望先扩展宏(在这种情况下你不能有双层宏,你需要直接做。)

关于c++ - 为什么我需要宏的双层间接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8231966/

相关文章:

c++ - C++ 是否仍被视为静态类型语言?

c++ - 在第一个 BST 上插入非空函数错误的结尾?

c++ - 为什么 MSVC 编译器将 "??-"序列转换为字符串文字中的 "~"?

c# - 在 C# 中查找包含宏的文档

c++ - 为字符串文字 C++ 引发编译器错误的宏

c++ - 从硬件异常处理程序中抛出 C++ 异常。为什么 -fnon-call-exceptions 的行为不如预期?

C++格式化以在行而不是列中显示数字

c++ - 如何从 vector<char> 转换为数字整数

c++ - 如何使用 blitz_0.9

C++ constexpr 与字符串文字中的宏与整数