标签: x-macros

真实使用X-Macros

我刚学会了X-Macros.您看过X-Macros的实际用途?他们什么时候成为工作的合适工具?

c macros c-preprocessor x-macros

67
推荐指数
5
解决办法
2万
查看次数

我可以附加到预处理器宏吗?

在标准C或GNU扩展中有什么方法可以将内容附加到宏定义中吗? 例如,给定一个宏定义为
#define List foo bar
可以追加,bas以便它List扩展,就像我定义它一样
#define List foo bar bas

我希望我能做到这样的事情:

#define List    foo bar bas

#define List_   Expand(List)
#undef List
#define List    Expand(List_) quux
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何定义Expand()宏,所以它会做我想要的.

动机: 我在这些方面玩歧视/标记的工会:

struct quux_foo { int x; };
struct quux_bar { char *s; };
struct quux_bas { void *p; };

enum quux_type {quux_foo, quux_bar, quux_bas};

struct quux {
    enum quux_type type;
    union {
        struct quux_foo foo;
        struct quux_bar bar;
        struct quux_bas bas;
    } t; …
Run Code Online (Sandbox Code Playgroud)

c macros c-preprocessor boost-preprocessor x-macros

9
推荐指数
2
解决办法
5143
查看次数

如何消除冗余宏参数

不久前,我为一个大型项目编写了一组X-macro.我需要维护字符串和枚举引用/哈希值/回调函数等的连贯列表.这是函数回调的样子

#define LREF_LOOKUP_TABLE_TEXT_SIZE 32
#define _LREF_ENUM_LIST(_prefix,_ref,...) _prefix ## _ ## _ref,
#define _LREF_BASE_STRUCT_ENTRY(_prefix,_ref) .text= #_ref "\0", .position= _LREF_ENUM_LIST(_prefix, _ref)
#define _LREF_FUNCTION_STRUCT_LIST(_prefix,_ref,...) {_LREF_BASE_STRUCT_ENTRY(_prefix,_ref) _prefix ## _ ## _ref ## _callback},

#define _LREF_ENUM_TYPEDEF(_prefix)                                               \ 
    typedef enum _prefix                                                          \  
    {                                                                             \  
        _ ## _prefix ## s(_prefix,_LREF_ENUM_LIST)                                \ 
        _LREF_ENUM_LIST(_prefix,tblEnd)                                           \ 
    } e_ ## _prefix

#define _LREF_LOOKUP_TABLE_TYPEDEF(_prefix, _extras)                              \ 
    typedef struct _prefix ## _lookup                                             \ 
    {                                                                             \ 
        const char text[LREF_LOOKUP_TABLE_TEXT_SIZE];                             \ 
        e_ ## _prefix position;                                                   \ 
        _extras                                                                   \ 
    } _prefix ##_lookup_t

#define LREF_GENERIC_LOOKUP_TABLE(_prefix, …
Run Code Online (Sandbox Code Playgroud)

c macros gcc c-preprocessor x-macros

6
推荐指数
1
解决办法
448
查看次数

Misra-C与X-macros兼容吗?

可以说,在许多情况下,X宏增加了安全性,因为例如,更容易确保生成的数组长度相同.


但是,Misra C(来自2004参考)规则似乎有很多限制使用的预处理器规则:

规则19.1(建议)文件中的#include语句应该只有其他预处理程序指令或注释开头.

如果源表位于包含的其他文件中,例如生成数组,则很麻烦.但这是一个咨询规则,因此可以解决.

规则19.4(必需)C宏只能扩展为支撑初始值设定项,常量,字符串文字,带括号的表达式,类型限定符,存储类说明符或do-while-zero结构.

不应该是问题,因为大多数X宏用于生成数组初始化器或常量.

规则19.6(必填)#undef不得使用.

使一些X-macro使用模式变得不可能.不幸的是,但并没有完全阻止X-macros.

规则19.7(建议)应该优先使用函数,而不是像函数一样的宏.

仅限咨询规则.

规则19.12(必需)在单个宏定义中最多只能出现一次#或##预处理器运算符.

可以使用嵌套宏来解决.

规则19.13(建议)不应使用#和##预处理器运算符.

例如,在生成枚举时很麻烦,但这只是一个建议规则.

规则19.15(必需)应采取预防措施,以防止头文件的内容被包含两次.

在某些情况下很麻烦,但可以解决.


看看上面的内容,如果你小心的话,似乎可以使用带有Misra C代码的X-macros.

我的结论是正确的,还是有一些我失踪的规则?

c misra x-macros

6
推荐指数
1
解决办法
296
查看次数

减少C++(或x-treme x-macros)中的代码重复

我正在使用x-macros来减少重复次数和代码重复,同时为游戏Bitfighter实现Lua接口.以下代码工作正常:

  //                            Fn name     Valid param profiles  Profile count                           
#  define TELEPORTER_LUA_METHOD_TABLE \
      TELEPORTER_LUA_METHOD_ITEM(addDest,    ARRAYDEF({{ PT,  END }}), 1 ) \
      TELEPORTER_LUA_METHOD_ITEM(delDest,    ARRAYDEF({{ INT, END }}), 1 ) \
      TELEPORTER_LUA_METHOD_ITEM(clearDests, ARRAYDEF({{      END }}), 1 ) \


// BLOCK A Start
const luaL_reg Teleporter::luaMethods[] =
{
#  define TELEPORTER_LUA_METHOD_ITEM(name, b, c) { #name, luaW_doMethod<Teleporter, &Teleporter::name > },
      TELEPORTER_LUA_METHOD_TABLE
#  undef TELEPORTER_LUA_METHOD_ITEM
   { NULL, NULL }
};
// BLOCK A End

  /* Generates the following:
  const luaL_reg Teleporter::luaMethods[] =
  { …
Run Code Online (Sandbox Code Playgroud)

c++ c-preprocessor x-macros

5
推荐指数
1
解决办法
860
查看次数

将宏名称传递到X宏列表是否合法

在我看来,以下是X宏技巧的首选样式:

#define LIST_OF_COLOURS(X) \
    X(RED) \
    X(GREEN) \
    X(BLUE)

#define LIST_OF_FRUIT(X) \
    X(APPLE) \
    X(ORANGE) \
    X(TOMATO)
Run Code Online (Sandbox Code Playgroud)

具体来说,将X宏传递给列表,而不是在每次实例化列表时都对其进行取消定义和重新定义。这允许:

#define X_LIST(x) x,
#define X_STRING_LIST(x) #x,
#define COMPREHENSIVE_SETUP(n, l)  \
    enum n { l(X_LIST) };  \
    char const* n##Names[] = { l(X_STRING_LIST) };

COMPREHENSIVE_SETUP(Colour, LIST_OF_COLOURS)
COMPREHENSIVE_SETUP(Fruit, LIST_OF_FRUIT)
Run Code Online (Sandbox Code Playgroud)

但是问题是我没有经常在野外看到这种习语,这不是Wikipedia所描述的,即使我每次尝试并觉得更方便的时候它似乎都可以工作。

我的问题是,这实际上合法且已完全定义,还是我依赖​​未定义的行为?

c c++ c-preprocessor x-macros

4
推荐指数
1
解决办法
58
查看次数

C - 如何在宏中分配值?

我试图在我的x-macro中分配一个值,但我真的不明白为什么它不起作用:

#include <stdio.h>

typedef struct
{
    int a;
    int b;
} struct_t;

#define MY_LIST \
    MY_ELEMENT(a) \
    MY_ELEMENT(b)

#define MY_ELEMENT(x) struct_t x; \ 
x.a=33;
MY_LIST 
#undef MY_ELEMENT

int main(void)
{
    fprintf(stdout, "a: %d\n", a.a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译时我收到以下错误:

test.c:14:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or   ‘__attribute__’ before ‘.’ token
 x.a=33;
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么我得到这个错误以及如何解决这个问题?

c x-macros

2
推荐指数
1
解决办法
632
查看次数

标签 统计

x-macros ×7

c ×6

c-preprocessor ×5

macros ×3

c++ ×2

boost-preprocessor ×1

gcc ×1

misra ×1