在##串联之前评估预处理器令牌 [英] Evaluate preprocessor token before ## concatenation

查看:140
本文介绍了在##串联之前评估预处理器令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想先评估一个令牌,然后再将其与其他对象连接. 问题"是该标准将行为指定为

I would like to evaluate a token before it is concatenated with something else. The "problem" is that the standard specifies the behaviour as

在重新检查替换列表之前,需要更多的宏名称 替换,替换中##预处理令牌的每个实例 列表(不是从参数中删除)并进行前面的预处理 令牌与以下预处理令牌串联.

before the replacement list is reexamined for more macro names to replace, each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token.

因此在以下示例中,

#include <stdlib.h>

struct xy {
    int x;
    int y;
};

struct something {
    char * s;
    void *ptr;
    int size;
    struct xy *xys;
};
#define ARRAY_SIZE(a) ( sizeof(a) / sizeof((a)[0]) )

#define DECLARE_XY_BEGIN(prefix) \
struct xy prefix ## _xy_table[] = {

#define XY(x, y) {x, y},

#define DECLARE_XY_END(prefix) \
    {0, 0} \
}; \
struct something prefix ## _something = { \
    "", NULL, \
    ARRAY_SIZE(prefix ## _xy_table), \
    &(prefix ## _xy_table)[0],  \
};

DECLARE_XY_BEGIN(linear1)
    XY(0, 0)
    XY(1, 1)
    XY(2, 2)
    XY(3, 3)
DECLARE_XY_END(linear1)


#define DECLARE_XY_BEGIN_V2() \
struct xy MYPREFIX ## _xy_table[] = {

#define DECLARE_XY_END_V2() \
    {0, 0} \
}; \
struct something MYPREFIX ## _something = { \
    "", NULL, \
    ARRAY_SIZE(MYPREFIX ## _xy_table), \
    &(MYPREFIX ## _xy_table)[0],  \
};

#define MYPREFIX linear2
DECLARE_XY_BEGIN_V2()
    XY(0, 0)
    XY(2, 1)
    XY(4, 2)
    XY(6, 3)
DECLARE_XY_END_V2()
#undef MYPREFIX

最后一个声明扩展为

struct xy MYPREFIX_xy_table[] = {
 {0, 0},
 {2, 1},
 {4, 2},
 {6, 3},
{0, 0} }; struct something MYPREFIX_something = { "", 0, ( sizeof(MYPREFIX_xy_table) / sizeof((MYPREFIX_xy_table)[0]) ), &(MYPREFIX_xy_table)[0], };

不是

struct xy linear2_xy_table[] = {
 {0, 0},
 {2, 1},
 {4, 2},
 {6, 3},
{0, 0} }; struct something linear2_something = { "", 0, ( sizeof(linear2_xy_table) / sizeof((linear2_xy_table)[0]) ), &(linear2_xy_table)[0], };

就像我想要的那样.有什么方法可以定义产生此结果的宏吗?第一组宏可以,但是我想避免前缀重复,并且只定义一次.那么可以用#define设置前缀并让宏使用它吗?

like I want to. Is there some way of defining macros that produces this? The first set of macros does, but I would like to avoid the prefix duplication and only have this defined once. So is it possible to set the prefix with #define and let the macros use that?

推荐答案

您可以为此使用二级扩展.

You can use second level expansion for this, eg.

#define XY_HLP1(a) DECLARE_XY_BEGIN(a)
#define XY_HLP2(a) DECLARE_XY_END(a)
#define DECLARE_XY_BEGIN_V2() XY_HLP1(MYPREFIX)
#define DECLARE_XY_END_V2() XY_HLP2(MYPREFIX)

这篇关于在##串联之前评估预处理器令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆