C宏扩展顺序

rnu*_*nes 6 c macros c-preprocessor

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

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

宏重复将扩展为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,
     ...
 }
Run Code Online (Sandbox Code Playgroud)

但是这会扩展为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,
     ...
 }
Run Code Online (Sandbox Code Playgroud)

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

chq*_*lie 3

您可以MACRO_REPEAT(ARRAY_LENGTH , -2)通过更改 的定义MACRO_REPEAT以使用两阶段扩展来解决此问题,即本身不使用标记粘贴MACRO_REPEAT,而是调用另一个这样做的宏。

并不是说,只有当ARRAY_LENGTH被定义为单个数字标记并且有针对该特定大小的宏定义时,这才会按预期工作。

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

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

#define MACRO_REPEAT(n, e)  [ 0 ... (n)-1 ] = e,
Run Code Online (Sandbox Code Playgroud)

但该方法不能用于处理诸如 之类的多维数组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) }) };
Run Code Online (Sandbox Code Playgroud)

但 C 预处理器的使用只是混淆了意图。如果您决定依赖 gcc 扩展,则直接使用它们即可。