C宏扩展顺序

时间:2016-07-15 12:55:10

标签: c macros c-preprocessor

我有一个宏来重复我用来在编译时用默认值填充数组的宏:

const int array [512] = 
{
     MACRO_REPEAT(512, -2) // this repeats -2, 512  times
     [4] = 10,
     [5] = 2,
     ...
}

宏重复将扩展为MACRO_REPEAT_512,但现在我想使用其他宏作为数组大小,如:

#define ARRAY_LENGTH 512
const int array [ARRAY_LENGTH ] = 
{
    MACRO_REPEAT(ARRAY_LENGTH , -2) // this repeats -2, 512  times
    [4] = 10,
    [5] = 2,
     ...
 }

但是这会扩展为MACRO_REPEAT_ARRAY_LENGTH,在连接之前不会扩展ARRAY_LENGTH值。其他例子是多维数组,涉及更多的扩展级别:

#define X 512
#define Y 512

const int array [X][Y] = 
{
    MACRO_REPEAT(X*Y , -2) // this repeats -2, 512  times
    [4] = 10,
    [5] = 2,
     ...
 }

这将扩展到MARO_REPEAT_X * Y.那么,有没有办法在将这些值连接到其他宏之前将它们扩展到最终的数值?

2 个答案:

答案 0 :(得分:1)

您可以通过更改MACRO_REPEAT(ARRAY_LENGTH , -2)的定义来解决MACRO_REPEAT案例,以使用2阶段扩展,即不要在MACRO_REPEAT本身使用令牌粘贴,调用另一个宏。{ / p>

如果将ARRAY_LENGTH定义为单个数字标记并且存在此特定大小的宏定义,则不会仅按预期工作。

使用标准C预处理器无法处理更一般的MACRO_REPEAT(X*Y , -2)情况。

您可以使用gcc扩展来初始化简单数组:

#define MACRO_REPEAT(n, e)  [ 0 ... (n)-1 ] = (e),

但是这种方法不能用于处理多维数组,例如MACRO_REPEAT(X*Y , -2)

你可以试试这个:

#define MACRO_REPEAT(n, e)  [ 0 ... (n)-1 ] = (e),
#define X 512
#define Y 512

const int array[X][Y] = { MACRO_REPEAT(X, { MACRO_REPEAT(Y, -2) }) };

但是使用C预处理器只是模糊了意图。如果您决定依赖gcc扩展,请直接使用它们。

答案 1 :(得分:1)

我不确定这是否算作“正确”的答案,因为它没有直接回答OP的问题,但这是针对该问题的建议解决方法。它也不是标准C,因为它使用了GCC扩展。

在GNU C编译器(gcc)中,可以使用[FIRST ... LAST] = VALUE形式将一系列数组元素初始化为相同的值。它似乎也允许一个元素的多个指定初始值设定项,因此可以将一系列元素初始化为相同的值,然后将该范围内包含的元素初始化为不同的值,如下所示:

#define ARRAY_LENGTH 512
const int array[ARRAY_LENGTH] =
{
    [0 ... ARRAY_LENGTH - 1] = -2,
    [4] = 10,
    [5] = 2,
    /* ... */
};