c - 替换 For 循环的宏

标签 c header macros c-preprocessor

考虑下面的宏。如何使用宏展开 for 循环并将大量宏干净地导出到可读的 header 中?

宏.h

#define ARR(n) \
typedef int arr##n[n]; \
void arr##n##_add(arr##n res, arr##n x, arr##n y){ \
    int i = 0; \
    for (; i < n; i++) { \
        res[i] = x[i] + y[i]; \
    } \
}

ARR(3)
ARR(4)

通过预处理器使用 gcc -E -P macro.h > out.h 运行它我们得到:

out.h

typedef int arr3[3]; 

void arr3_add(arr3 res, arr3 x, arr3 y){ 
    int i = 0; 
    for (; i < 3; i++) { 
        res[i] = x[i] + y[i]; 
    } 
}

typedef int arr4[4]; 

void arr4_add(arr4 res, arr4 x, arr4 y){ 
    int i = 0; 
    for (; i < 4; i++) { 
        res[i] = x[i] + y[i]; 
    } 
}

使用token pasting像上面一样,我们避免重复定义。现在有两件事我想知道:

  1. 如何每个 for(;i; i < n)替换(展开)为例如:

    res[0] = x[0] + y[0];
    res[1] = x[1] + y[1];
    ...
    res[n] = x[n] + y[n];
    
  2. 将大量宏黑客行为导出到可读 header 中的干净方法是什么?我应该在我的 make 中创建一个 shell 函数吗?文件将最终 header 导出到 include目录?

也许有更好的方法可以做到这一点。欢迎任何替代方案。

最佳答案

这是 answer 引用的一种可能的解决方案使用these macro functions :

#define ARR(n, m) \
static inline void vec##n##_add(vec##n res, \
        vec##n const u, vec##n const v) { \
        m }

#define ADD(i, n) res[i] = u[i] + v[i]; 
ARR(3, EVAL(REPEAT(3, ADD, ~)))
ARR(4, EVAL(REPEAT(4, ADD, ~)))

它按照要求执行,但以一种复杂、黑客、丑陋的方式......特别是,使用递归宏来执行应该是迭代的操作。

关于c - 替换 For 循环的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34247892/

相关文章:

c - 将窗口大小调整为 X 个字符(不是像素)

c++ - 在 C++ 中,以这种方式包括有问题吗?

Apache 配置读取 header 值

c++ - 使用具有设置延迟 C++ 的 mouse_event 平滑鼠标移动

c - 如何使用 GNU C 预处理器预定义宏?

c - 如何在 C 中读取 .txt

c++ - 为字符串生成不同的条目(要使用的点)

c - 如何查看输入的值是数字而不是字符?

header - RabbitMQ:如何在 Header Exchange 中使用复杂的表达式?

emacs - elisp mapcar + lambda + defmacro 帮助