#define中的##是什么意思?

Dan*_*ode 32 c c++ c-preprocessor

这条线是什么意思?特别是,是什么##意思?

#define ANALYZE(variable, flag)     ((Something.##variable) & (flag))

编辑:

有点困惑.没有结果会是##什么?

ybu*_*ill 18

有点困惑.没有##会有什么结果?

通常你不会注意到任何差异.但有有差别.假设Something是类型:

struct X { int x; };
X Something;
Run Code Online (Sandbox Code Playgroud)

看看:

int X::*p = &X::x;
ANALYZE(x, flag)
ANALYZE(*p, flag)
Run Code Online (Sandbox Code Playgroud)

没有令牌连接运算符##,它扩展为:

#define ANALYZE(variable, flag)     ((Something.variable) & (flag))

((Something. x) & (flag))
((Something. *p) & (flag)) // . and * are not concatenated to one token. syntax error!
Run Code Online (Sandbox Code Playgroud)

使用令牌连接,它扩展为:

#define ANALYZE(variable, flag)     ((Something.##variable) & (flag))

((Something.x) & (flag))
((Something.*p) & (flag)) // .* is a newly generated token, now it works!
Run Code Online (Sandbox Code Playgroud)

重要的是要记住预处理器在预处理器令牌上运行,而不是在文本上运行.因此,如果要连接两个令牌,则必须明确说出来.


Naw*_*waz 12

## 称为标记连接,用于在宏调用中连接两个标记.

看到这个:

  • 实际上它被称为令牌连接.我不认为IBM AIX C/C++编译器的文档是最好的参考! (3认同)

fyr*_*fyr 9

一个非常重要的部分是这个标记连接遵循一些非常特殊的规则:

例如IBM doc:

  • 在扩展参数中的任何宏之前进行连接.
  • 如果连接的结果是有效的宏名称,即使它出现在通常不可用的上下文中,它也可用于进一步替换.
  • 如果宏定义的替换列表中出现多个 ##运算符和/或#运算符,则不定义运算符的计算顺序.

例子也很自我解释

#define ArgArg(x, y)          x##y
#define ArgText(x)            x##TEXT
#define TextArg(x)            TEXT##x
#define TextText              TEXT##text
#define Jitter                1
#define bug                   2
#define Jitterbug             3
Run Code Online (Sandbox Code Playgroud)

随着输出:

ArgArg(lady, bug)   "ladybug"
ArgText(con)    "conTEXT"
TextArg(book)   "TEXTbook"
TextText    "TEXTtext"
ArgArg(Jitter, bug)     3
Run Code Online (Sandbox Code Playgroud)

Source是IBM文档.可能与其他编译器有所不同.

你的路线:

它将变量属性连接到"Something".并且处理一个逻辑上为anded的变量,如果Something.variable设置了一个标志,则该变量会给出结果.

这是我上次评论和你的问题的一个例子(用g ++编译):

// this one fails with a compiler error
// #define ANALYZE1(variable, flag)     ((Something.##variable) & (flag))
// this one will address Something.a (struct)
#define ANALYZE2(variable, flag)     ((Something.variable) & (flag))
// this one will be Somethinga (global)
#define ANALYZE3(variable, flag)     ((Something##variable) & (flag))
#include <iostream>
using namespace std;

struct something{
int a;
};

int Somethinga = 0;

int main()
{
something Something;
Something.a = 1;

if (ANALYZE2(a,1))
    cout << "Something.a is 1" << endl;
if (!ANALYZE3(a,1))
    cout << "Somethinga is 0" << endl;
        return 1;
};
Run Code Online (Sandbox Code Playgroud)