繁体   English   中英

如何让预处理器宏在编译前评估代码

[英]How do i make preprocessor macros evaluate code before compilation

我正在使用宏来为我的代码中的某些数组定义静态大小,我在我的代码顶部定义了一个配置宏变量,并且一些宏变量取决于所述宏变量。 我可以创建一个函数来获取该值并返回所需的数组大小,但这将在运行时执行,我需要使用 VLA。 下面的示例显示了数字大小(没有重复数字)的宏以及该数字是否可以以零开头(“0123”与“1234”)。

在运行时计算 LIMIT 的代码:

int limit(int size, int npz){
    l = npz ? 9 : 10;
    for(int i = 1; i < size; i++)
        l *= 10 - i;
    return l;
}

我手动计算了所有值的所述数字的数量。 有解决办法吗?

#define SIZE 4 // 1 .. 10
#define NO_PADDING_ZERO 1 // 1 | 0
#if NO_PADDING_ZERO
    #if SIZE == 1
        #define LIMIT 9
    #elif SIZE == 2
        #define LIMIT 81
    #elif SIZE == 3
        #define LIMIT 648
    #elif SIZE == 4
        #define LIMIT 4536
    #elif SIZE == 5
        #define LIMIT 27216
    #elif SIZE == 6
        #define LIMIT 136080
    #elif SIZE == 7
        #define LIMIT 544320
    #elif SIZE == 8
        #define LIMIT 1632960
    #else
        #define LIMIT 3265920
    #endif
#else
    #if SIZE == 1
        #define LIMIT 10
    #elif SIZE == 2
        #define LIMIT 90
    #elif SIZE == 3
        #define LIMIT 720
    #elif SIZE == 4
        #define LIMIT 5040
    #elif SIZE == 5
        #define LIMIT 30240
    #elif SIZE == 6
        #define LIMIT 151200
    #elif SIZE == 7
        #define LIMIT 604800
    #elif SIZE == 8
        #define LIMIT 1814400
    #else
        #define LIMIT 3628800
    #endif
#endif

解决方法可能是从其他东西生成C 代码。

考虑学习更多,使用GPP或您自己的 C 代码生成器(可能使用GNU bison ,在某些简单的情况下使用GNU gawkGNU autoconf )。

请注意,在 Linux 或 POSIX 上,您可以生成 C 代码,将其编译为插件,然后dlopen(3)该插件。 有关无用的示例,请参阅manydl.c 有关有用(但已过时)的示例,请参阅我的旧GCC MELT

另一种方法(特定于GCC )可能是使用GCC 插件扩展您的编译器。 比斯蒙

您还可以使用GNU Lightning或(在 C++ 中) asmjit生成机器代码(在您的程序中)。 然后阅读龙书这个答案。

阅读Jacques Pitrat的一些书籍,解释元编程方法(在RefPerSys中重用)

部分评估相关的概念是相关的。

这是某种阶乘吗?

(10 - NO_PADDING_ZERO) * 9 * 8 * ... * (10 - LIMIT)

您可以在宏或内联函数的循环表达式中使用它,优化编译器将在编译时计算它。

#include <bool.h>

inline int limit(int size, bool npz){
    int l = 10 - npz;
    for(int i = 1; i < size; i++)
        l *= 10 - i;
    return l;
}

#define LIMIT (limit(SIZE, NO_PADDING_ZERO))

如果您愿意,您可以定义一个预先计算的数组并使用

#define LIMIT (array[SIZE][NO_PADDING_ZERO])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM