预处理器由于以下原因而失败

预处理器由于以下原因而失败

本文介绍了预处理器由于以下原因而失败--'#'后没有宏参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我试图简化数组的声明,但是遇到了我使用的预处理器的问题.我的初始代码如下:

I am trying to simplify the declaration of an array, but ran into an issue with the preprocessors that I am using. My initial code looks like the following:

#define REQ_ENTRY(parm_1, parm_2)    \
#if defined(parm_1)                  \
    { parm_1, parm_2 },              \
#endif

typedef struct {
    int parm1,
        parm2;
} MyTypedef_t;

static const MyTypedef_t MyList[] =
{
    REQ_ENTRY( ID_1, 1 )
    REQ_ENTRY( ID_2, 2 )
    REQ_ENTRY( ID_3, 3 )
    REQ_ENTRY( ID_4, 4 )
    REQ_ENTRY( ID_5, 5 )
};

当然,构建失败,并显示错误消息错误:'#'后没有宏参数".此处说明了其原因(为什么编译器会抱怨此宏声明)

The build fails, of course, with the error message of "error: '#' is not followed by a macro parameter". The reason for this is explained here (Why compiler complain about this macro declaration)

基本上,我试图避免按以下方式声明数组,但这确实有效:

Basically, I am trying to avoid declaring the array as the follows, which does work:

static const MyTypedef_t MyList[] =
{
    #if defined (ID_1)
    { ID_1, 1 },
    #endif

    #if defined (ID_2)
    { ID_2, 2 },
    #endif

    #if defined (ID_3)
    { ID_3, 3 },
    #endif

    #if defined (ID_4)
    { ID_4, 4 },
    #endif

    #if defined (ID_5)
    { ID_5, 5 },
    #endif
};

该列表可能会很长,并且会根据项目的构建类型而有所不同.我曾尝试过考虑使用x-macros,但我想我也会遇到同样的问题.我希望有人能看到一种创建预处理器宏的方式,从而可以实现原始的Sugar语法?任何见解都将不胜感激.

The list can be rather long and vary depending upon the build type of the project. I have tried thinking of using x-macros, but I think I would have the same issue. I am hoping someone might see a way of creating the preprocessor macros in such a way that I could achieve the original sugar syntax? Any insight is greatly appreciated.

推荐答案

没有好的解决方案.但是,有一些解决方案可以解决各种丑陋问题.

There is no nice clean solution. But there are solutions of varying ugliness.

如果您不介意在宏定义中同时包含 id 序列,则可以这样解决:

If you don't mind including both the id and the sequence in the macro definition, it can be solved like this:

#define CONCAT2(x,y) x##y
#define CONCAT(x,y) CONCAT2(x,y)
#define REQ_ENTRY_YES(p1, p2) { p1 , p2 }
#define REQ_ENTRY_NO(p1)
#define IS_PAIR_HELPER(a, b, c, ...) c
#define IS_PAIR(...) IS_PAIR_HELPER(__VA_ARGS__, YES, NO)
#define REQ_ENTRY(pair) CONCAT(REQ_ENTRY_, IS_PAIR(pair))(pair)

#define ID_1 78723649, 1
#define ID_3 2347602, 3

typedef struct {
    int parm1,
        parm2;
} MyTypedef_t;

static const MyTypedef_t MyList[] =
{
    REQ_ENTRY( ID_1 )
    REQ_ENTRY( ID_2 )
    REQ_ENTRY( ID_3 )
    REQ_ENTRY( ID_4 )
    REQ_ENTRY( ID_5 )
};


使用-std=c11 -Wall -E运行gcc,并仅显示MyList定义:


Run through gcc with -std=c11 -Wall -E, and showing only the MyList definition:

static const MyTypedef_t MyList[] =
{
    { 78723649 , 1 }

    { 2347602 , 3 }


};


只要有一个,就可以通过在#define ID_x宏中使用 any 第二个值来执行相同的操作;实际参数可以添加到REQ_ENTRY.但这需要一些额外的杂耍.


You can do the same thing by using any second value in the #define ID_x macros, as long as there is one; the real parameters can be added to REQ_ENTRY. But it takes some extra juggling.

这篇关于预处理器由于以下原因而失败--'#'后没有宏参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 11:59