【问题标题】:C macro expansion of a function pointer based on for loop incrementor基于for循环增量器的函数指针的C宏扩展
【发布时间】:2025-11-23 02:25:01
【问题描述】:

我有一个函数,它将指向函数的指针作为参数。 由于函数指针名称的相似性质,此函数在 for 循环中被调用,我使用宏将名称扩展为函数。它看起来像这样:

void fill(int, int(*funcbase)(int));
int funcbase0(int);
int funcbase1(int);
int funcbase2(int);
int funcbase3(int);
/// all the way through funcbase31

#define FILL_(num) fill(num, funcbase##num)
#define FILL(num) FILL_(num)

for(int i = 0; i < 32; i++)
    FILL(i);

我希望这个为 0,1,2,... 和 funcbase0, funcbase1, funcbase2,... 调用填充,但它使用“funcbasei”的第二个参数调用填充它不会每次都扩展 i .

我正在尝试做的事情可能吗?我需要尝试什么编译器? (我使用的是 gcc 4.9.3)

【问题讨论】:

    标签: c macros variadic-macros


    【解决方案1】:

    您尝试使用宏无法执行此操作,因为宏在编译时展开,远在运行时和循环开始运行之前。

    但是,您可以通过函数指针数组上的for 循环轻松地做到这一点:

    typedef int(*funcbase_t)(int);
    funcbase_t fbases[] = {
        funcbase0, funcbase1, funcbase2, funcbase3, ...
    };
    

    现在您可以在 fbase 数组上运行循环:

    for(int i = 0; i < 32; i++)
        fbases[i](i);
    

    【讨论】:

    • 谢谢我想了很多,有趣的方法!我应该提到有 256 个 funcbase,我怀疑我会手动输入它。我可能会编写一个 bash 或 python 脚本并将其添加到我的代码中。
    【解决方案2】:

    您可以使用预处理器来执行此操作,方法是将间隔递归地拆分为多个部分并为每个部分调用它。或者使用 boost 中的预建版本:

    #include <boost/preprocessor/repetition/repeat.hpp>
    
    // and in code
    #define FILL_(num) fill(num, funcbase##num)
    #define FILL(num) FILL_(num)
    #define MACRO(z, n, text) FILL_(n);
    
    BOOST_PP_REPEAT(4, MACRO, 0);
    

    【讨论】:

    • 这是个好主意!不幸的是,对于我的情况,提升不是一种选择。我仍然相信其他人可能会觉得这很有用!谢谢!