如何生成给定大小的#define列表

时间:2014-06-03 19:00:14

标签: c xcode

我使用以下代码生成一个列表(稍后在x宏中使用)


#define LIST_OF_VARIABLES \
    X(value1) \
    X(value2) \
    X(value3) \
    X(value4) \
    X(value5) \
    X(value6) \
    X(value7)

有没有办法生成给定大小为N的列表。结果列表包含从value0到valueN的元素?

我正在使用以下X宏

#define X(name)  unsigned long long int name;
    LIST_OF_VARIABLES
#undef X
#define X(name) name =idx;
    LIST_OF_VARIABLES
#undef X

并生成此输出




 value1 =idx; value2 =idx; value3 =idx; value4 =idx; value5 =idx; value6 =idx; value7 =idx;


感谢M Oehm解决方案


//#################Q VAR GENERATION#################
#define VAR(P, NNN, NN, N) P##NNN##NN##N

#define NUM0(P, X, NNN, NN)                      X(VAR(P, NNN, NN, 0))
#define NUM1(P, X, NNN, NN) NUM0(P, X, NNN, NN) X(VAR(P, NNN, NN, 1))
#define NUM2(P, X, NNN, NN) NUM1(P, X, NNN, NN) X(VAR(P, NNN, NN, 2))
#define NUM3(P, X, NNN, NN) NUM2(P, X, NNN, NN) X(VAR(P, NNN, NN, 3))
#define NUM4(P, X, NNN, NN) NUM3(P, X, NNN, NN) X(VAR(P, NNN, NN, 4))
#define NUM5(P, X, NNN, NN) NUM4(P, X, NNN, NN) X(VAR(P, NNN, NN, 5))
#define NUM6(P, X, NNN, NN) NUM5(P, X, NNN, NN) X(VAR(P, NNN, NN, 6))
#define NUM7(P, X, NNN, NN) NUM6(P, X, NNN, NN) X(VAR(P, NNN, NN, 7))
#define NUM8(P, X, NNN, NN) NUM7(P, X, NNN, NN) X(VAR(P, NNN, NN, 8))
#define NUM9(P, X, NNN, NN) NUM8(P, X, NNN, NN) X(VAR(P, NNN, NN, 9))

#define NUM(P, X, NNN, NN, N) NUM##N(P, X, NNN, NN)

#define NNUM0(P, X, NNN, N)                      NUM(P, X, NNN, 0, N)
#define NNUM1(P, X, NNN, N) NNUM0(P, X, NNN, 9) NUM(P, X, NNN, 1, N)
#define NNUM2(P, X, NNN, N) NNUM1(P, X, NNN, 9) NUM(P, X, NNN, 2, N)
#define NNUM3(P, X, NNN, N) NNUM2(P, X, NNN, 9) NUM(P, X, NNN, 3, N)
#define NNUM4(P, X, NNN, N) NNUM3(P, X, NNN, 9) NUM(P, X, NNN, 4, N)
#define NNUM5(P, X, NNN, N) NNUM4(P, X, NNN, 9) NUM(P, X, NNN, 5, N)
#define NNUM6(P, X, NNN, N) NNUM5(P, X, NNN, 9) NUM(P, X, NNN, 6, N)
#define NNUM7(P, X, NNN, N) NNUM6(P, X, NNN, 9) NUM(P, X, NNN, 7, N)
#define NNUM8(P, X, NNN, N) NNUM7(P, X, NNN, 9) NUM(P, X, NNN, 8, N)
#define NNUM9(P, X, NNN, N) NNUM8(P, X, NNN, 9) NUM(P, X, NNN, 9, N)

#define NNUM(P, X, NNN, NN, N) NNUM##NN(P, X, NNN, N)

#define NNNUM0(P, X, NN, N)                      NNUM(P, X, 0, NN, N)
#define NNNUM1(P, X, NN, N) NNNUM0(P, X, 9, NN) NNUM(P, X, 1, NN, N)
#define NNNUM2(P, X, NN, N) NNNUM1(P, X, 9, NN) NNUM(P, X, 2, NN, N)
#define NNNUM3(P, X, NN, N) NNNUM2(P, X, 9, NN) NNUM(P, X, 3, NN, N)
#define NNNUM4(P, X, NN, N) NNNUM3(P, X, 9, NN) NNUM(P, X, 4, NN, N)
#define NNNUM5(P, X, NN, N) NNNUM4(P, X, 9, NN) NNUM(P, X, 5, NN, N)
#define NNNUM6(P, X, NN, N) NNNUM5(P, X, 9, NN) NNUM(P, X, 6, NN, N)
#define NNNUM7(P, X, NN, N) NNNUM6(P, X, 9, NN) NNUM(P, X, 7, NN, N)
#define NNNUM8(P, X, NN, N) NNNUM7(P, X, 9, NN) NNUM(P, X, 8, NN, N)
#define NNNUM9(P, X, NN, N) NNNUM8(P, X, 9, NN) NNUM(P, X, 9, NN, N)

#define NNNUM(P, X, NNN, NN, N) NNNUM##NNN(P, X, NN, N)

//#####################Q var count####################
#define QA(X) NNNUM(qA, X, 0, 1, 6)
#define QB(X) NNNUM(qB, X, 0, 1, 6)
//####################################################

#define INIT(A) unsigned long long int A=EMPTY_STATE_VALUE;
#define TEST(A)  res[0]=A;


//in code
    QB(INIT);
    QA(TEST);

5 个答案:

答案 0 :(得分:2)

首先,我同意John Bode的回答,因为我怀疑你试图完成的事情可以通过其他一些构造更优雅地完成,而不是依赖于预处理器宏。即使你不同意“#em; macros is evil"”的常识,他们仍然是丑陋的,难以调试,而且往往容易出错且不便携。我的建议是采取不同的方法 - 最好不要依赖预处理器技巧。

如上所述,here指出,有一个Boost预处理器库可以编写预处理器循环。

以下是一个示例(来自this page on boost.org):

#include <boost/preprocessor/iteration/local.hpp>

template<int> struct sample;

#define BOOST_PP_LOCAL_MACRO(n) \
   template<> struct sample<n> { \
      enum { value = n }; \
   }; \
   /**/

#define BOOST_PP_LOCAL_LIMITS (1, 5)

#include BOOST_PP_LOCAL_ITERATE()
/* expands to...
template<> struct sample<1> { enum { value = 1 }; };
template<> struct sample<2> { enum { value = 2 }; };
template<> struct sample<3> { enum { value = 3 }; };
template<> struct sample<4> { enum { value = 4 }; };
template<> struct sample<5> { enum { value = 5 }; };
*/

答案 1 :(得分:1)

不在预处理器本身内;在宏扩展之前识别所有预处理器定义; IOW,您无法定义扩展为#define的宏并且预处理器可以识别该定义。

您可以编写一个生成该宏的小型实用程序,您可以将其保存到头文件中。

...然而

通常情况下,当你需要一堆相同类型的变量并且仅由序数(value0value1value2,......)区分时,你会使用数组。是否有任何特殊原因导致数组在您的情况下无用?

答案 2 :(得分:1)

哦,它可以在预处理器中完成。的种类。我不认为生成的枚举是有用的,或者方法是优雅的,但在预处理器中做事总是给出成就感。就像用针织针打开烤豆罐头一样。早上三点钟。

Anayway,这是一种允许您定义N个枚举变量的方法。您必须将N指定为单独的数百,数十和1,但是:

#define VAR(P, NNN, NN, N) P##NNN##NN##N

#define NUM0(P, X, NNN, NN)                      X(VAR(P, NNN, NN, 0))
#define NUM1(P, X, NNN, NN) NUM0(P, X, NNN, NN), X(VAR(P, NNN, NN, 1))
#define NUM2(P, X, NNN, NN) NUM1(P, X, NNN, NN), X(VAR(P, NNN, NN, 2))
#define NUM3(P, X, NNN, NN) NUM2(P, X, NNN, NN), X(VAR(P, NNN, NN, 3))
#define NUM4(P, X, NNN, NN) NUM3(P, X, NNN, NN), X(VAR(P, NNN, NN, 4))
#define NUM5(P, X, NNN, NN) NUM4(P, X, NNN, NN), X(VAR(P, NNN, NN, 5))
#define NUM6(P, X, NNN, NN) NUM5(P, X, NNN, NN), X(VAR(P, NNN, NN, 6))
#define NUM7(P, X, NNN, NN) NUM6(P, X, NNN, NN), X(VAR(P, NNN, NN, 7))
#define NUM8(P, X, NNN, NN) NUM7(P, X, NNN, NN), X(VAR(P, NNN, NN, 8))
#define NUM9(P, X, NNN, NN) NUM8(P, X, NNN, NN), X(VAR(P, NNN, NN, 9))

#define NUM(P, X, NNN, NN, N) NUM##N(P, X, NNN, NN)

#define NNUM0(P, X, NNN, N)                      NUM(P, X, NNN, 0, N)
#define NNUM1(P, X, NNN, N) NNUM0(P, X, NNN, 9), NUM(P, X, NNN, 1, N)
#define NNUM2(P, X, NNN, N) NNUM1(P, X, NNN, 9), NUM(P, X, NNN, 2, N)
#define NNUM3(P, X, NNN, N) NNUM2(P, X, NNN, 9), NUM(P, X, NNN, 3, N)
#define NNUM4(P, X, NNN, N) NNUM3(P, X, NNN, 9), NUM(P, X, NNN, 4, N)
#define NNUM5(P, X, NNN, N) NNUM4(P, X, NNN, 9), NUM(P, X, NNN, 5, N)
#define NNUM6(P, X, NNN, N) NNUM5(P, X, NNN, 9), NUM(P, X, NNN, 6, N)
#define NNUM7(P, X, NNN, N) NNUM6(P, X, NNN, 9), NUM(P, X, NNN, 7, N)
#define NNUM8(P, X, NNN, N) NNUM7(P, X, NNN, 9), NUM(P, X, NNN, 8, N)
#define NNUM9(P, X, NNN, N) NNUM8(P, X, NNN, 9), NUM(P, X, NNN, 9, N)

#define NNUM(P, X, NNN, NN, N) NNUM##NN(P, X, NNN, N)

#define NNNUM0(P, X, NN, N)                      NNUM(P, X, 0, NN, N)
#define NNNUM1(P, X, NN, N) NNNUM0(P, X, 9, NN), NNUM(P, X, 1, NN, N)
#define NNNUM2(P, X, NN, N) NNNUM1(P, X, 9, NN), NNUM(P, X, 2, NN, N)
#define NNNUM3(P, X, NN, N) NNNUM2(P, X, 9, NN), NNUM(P, X, 3, NN, N)
#define NNNUM4(P, X, NN, N) NNNUM3(P, X, 9, NN), NNUM(P, X, 4, NN, N)
#define NNNUM5(P, X, NN, N) NNNUM4(P, X, 9, NN), NNUM(P, X, 5, NN, N)
#define NNNUM6(P, X, NN, N) NNNUM5(P, X, 9, NN), NNUM(P, X, 6, NN, N)
#define NNNUM7(P, X, NN, N) NNNUM6(P, X, 9, NN), NNUM(P, X, 7, NN, N)
#define NNNUM8(P, X, NN, N) NNNUM7(P, X, 9, NN), NNUM(P, X, 8, NN, N)
#define NNNUM9(P, X, NN, N) NNNUM8(P, X, 9, NN), NNUM(P, X, 9, NN, N)

#define NNNUM(P, X, NNN, NN, N) NNNUM##NNN(P, X, NN, N)

然后你可以在X宏中使用它:

#define ENUM(A) A
#define STRING1(A) #A
#define STRING(A) STRING1(A)

#define LIST_OF_VARIABLES(X) NNNUM(dalmatian, X, 1, 0, 0)

enum {
    LIST_OF_VARIABLES(ENUM)
};

const char *varname[] = {
    LIST_OF_VARIABLES(STRING)
}

这将生成101个枚举值,称为dalmatian000damtaian100加上相应的字符串实体。它们将以逗号分隔;您可以通过删除宏替换中的顶级逗号来更改此内容。

系统可以扩展超过1000个条目。

宏对于生成数字没有用,因为较低的值最终会有前导零,这使得它们成为八进制常量。但是生成十六进制常量应该很容易。

答案 3 :(得分:0)

没办法,但你可以添加一个循环(如果你知道如何生成值):

#define LIST_OF_VARIABLES(low, high) for(int i=low; i <= high; i++) { X(i); };

答案 4 :(得分:0)

有点不清楚你的意思&#34; list&#34;。我有点假设你想要某种像

这样的变量分区
X(value0)
X(value1)
...
X(valuen)

但是你可以任意&#34;砍掉&#34;从结束,或可能开始,或两者的价值。答案是否定的,但您可以使用以下内容进行模拟:

<强> values_x.h

#ifdef USE_VALUES_X_VALUE0
X(value0)
#endif
X(value1)
X(value2)
X(value3)
X(value4)
X(value5)
X(value6)
X(value7)
#ifdef USE_VALUES_X_TO_VALUEN
X(value8)
...
X(valuen)
#endif

因此,对于变量列表,您可以使用此文件:

#undef USE_VALUES_X_VALUE0
#undef USE_VALUES_X_TO_VALUEN
#define X(x_) unsigned long long int x_ = idx; // X-Macro code goes here
#include "values_x.h"

这就像LIST_OF_VARIABLES

另一种方法是使用像GNU Autogen这样的代码生成工具 为您生成不同的X-Macros标头(基本上从标头中删除#include逻辑如上所示,并将其放入自动模板/数据文件中。)