使用结构解引用运算符在C中粘贴令牌

时间:2012-12-05 02:36:26

标签: c structure token c-preprocessor dereference

我有一个关于' ##'的问题用于使用解除引用运算符进行预处理器粘贴。谁能告诉我为什么下面的代码不能编译?

typedef struct
{
    char data;
} MY_STRUCT;

MY_STRUCT  My_Instance;
MY_STRUCT* My_PInstance;

#if 1
#define GET_MEMBER(membername)         (My_PInstance->##membername)
#else
#define GET_MEMBER(membername)         (My_Instance.##membername)
#endif

然后我打电话:

char value = GET_MEMBER(data);  // Where My_PInstance is properly instantiated.

我收到编译错误。

error: pasting "->" and "data" does not give a valid preprocessing token

2 个答案:

答案 0 :(得分:5)

您无需粘贴。 只需(My_Pinstance->membername)

'##'应将两个令牌粘贴到一个有效令牌中。然而 ->foo无效令牌。 (例如foo)

答案 1 :(得分:2)

对于任何以这种方式来的人。我有同样的问题,但是'。'未讨论的GET_MEMBER(..)宏的变体,但我认为问题是相同的。

我犹豫地接受了cwyang的回答,因为真正被粘贴的是文字

My_PInstance->

data

用 - 我的(和用户......)思考 - 结果是一个合适的标记。

My_PInstance->data

所以,我坚持通过更多的谷歌搜索结果。最后我来到this guy,他给出了一个真正的打击历史记录。总结:

回到古老的tymes,存在一种古老的替代语法,但没有编译器再次认识到这些废话。甚至不去那里。

曼。这家伙说没有希望......

哎呀,到底是什么?我去了那儿。替代语法有效,我使用古老的编译器 几乎

g++ (GCC) 4.7.3
Copyright (C) 2012 Free Software Foundation, Inc.

所以,对于所有你勇敢的字符串化器和连接符和标记符(!),这是我的教训。

之前:

#define PROFILING_START_CLK(STAT, n)                        \
    time0##STAT##n = PRF_CLK_FN();                          \
    profilingStatsIndex##STAT##n = STAT##.count % PROFILE_SIZE; \
    STAT#.count++;

这样称呼:

PROFILING_START_CLK(tst, 0);

为每个使用的地方返回以下错误的2个内容:

error: pasting "tst" and "." does not give a valid preprocessing token

就像user1159503一样。

继续前进...... 以下作品:

#define PROFILING_START_CLK(STAT, n)                          \
    time0##STAT##n = PRF_CLK_FN();                            \
    profilingStatsIndex##STAT##n = STAT/**/.count % PROFILE_SIZE;\
---------------------------------------^^^^
    STAT/**/.count++;
--------^^^^

无论是否使用g ++ -ansi开关,前/后版本都失败/编译。

它起作用的原因是因为预处理器在进入宏之前删除了注释,所以顺序是这样的。

    当 STAT与.count相邻。
  1. 避免了'##'过程。特别是,在代码中此时避免检查有效的结果令牌。
  2. STAT被字符串化为'tst'(在我的情况下)
  3. 后续的解析/令牌检查发现'tst.count'非常合适且令人满意。
  4. '##'应该在宏中组合任意结构和/或成员吗?我不知道。我会这么认为,但对于不跨越运营商的粘贴过程来说似乎也是正确的。

    否则,问题是,“粘贴过程是否合理只是”加入“像我们在这里谈论的那样的运营商。('。',' - >','::',.. ..)“