宏执行整数算术运算

4

能否使用宏进行算术运算(例如乘法)?

我理解编写如下宏:

#define mult(a,b) ((a)*(b))

将产品替换到所有地方。但我有两个参数都是常量。我知道编译器也会静态执行乘法,但问题是我必须使用#将结果转换为字符串。

有什么想法吗?

如果可以使用C ++宏完成,我还可以。我可以在C ++中编写这些特定模块并将其链接起来。

以下是我的现有代码

#define ARG_COPY()      __asm__("subq   $8, %rsp"); \
                        __asm__("movq   %gs:0xe8, %r10"); \
                        __asm__("movq   $16, %r11"); \
                        __asm__("1:"); \
                        __asm__("movq   -8(%r10, %r11, 8), %rax"); \
                        __asm__("pushq  %rax"); \
                        __asm__("decq   %r11"); \
                        __asm__("jne    1b"); \

#define ARG_REMOVE()    __asm__("add    $136, %rsp"); 

现在上面的代码没有参数——136是16*8+8。我想将那个16变成一个参数。第一个宏中也使用了同样的16。


对于这种情况,我们使用文本处理(主要是awk)从文本中创建C/C++源代码(大多数是使用电子表格应用程序编辑的制表符分隔文件)。这简化了源代码的维护。必要时,调试仍然使用C/C++。由于CMake(以及我的同事的努力),我们可以将awk预处理包含到构建链中——它甚至在Visual Studio中运行良好。(我从未注意到这些文本文件有任何依赖项解决问题。)这既不优雅也不复杂,但非常健壮且易于处理。 - Scheff's Cat
@Scheff 我已经在使用 python 生成一些汇编文件了。这次我也会这样做。只是想避免创建另一个文件格式来提供这些常量。无论如何,谢谢! - Ajay Brahmakshatriya
如果你总是将某个数字乘以 8(2的幂),为什么不使用类似 #define mul8(a) ((a) << 3) 的东西呢?这样,对于无符号值0-15,乘法可以正常工作,而不会有溢出的风险。 - David C. Rankin
@DavidC.Rankin 但我必须在字符串内使用它。我必须使用##运算符将结果转换为字符串。如果我在你提到的内容上使用它,我会得到"((7) << 3)"。这对我没用。 - Ajay Brahmakshatriya
2个回答

4
不行。C预处理器仅在标记上操作(通过用另一个标记序列替换一个标记序列)。它不会在之间进行算术运算。
你需要编写自己的预处理器来实现这一点。或者创建包含产品字符串的头文件,并在需要时进行#include?还有另一种可能性:如果它不是真正的性能瓶颈,那就不要费心了;使用sprintf(s,“%d”,mult(a,b))。也许某些编译器足够聪明,可以在编译时计算出这个值。
你有多少个常量产品字符串?其中有多少个不同的?

是的,所以我必须始终将一个参数乘以8。而参数的可能值可以像0-15这样。我知道我可以编写类似mult_0、mult_15的宏,并从mult中调用它们。我只是希望有更好的解决方法。 - Ajay Brahmakshatriya
@Jens 除非有其他的宏生成,否则 mult(15,8) 不会直接出现以供 sed 处理。 - Ajay Brahmakshatriya
@AjayBrahmakshatriya 你是否控制着生成多个语句的程序?那么我会在源代码上修复问题,而不是在其上打补丁。 - Jens
@Potatoswatter 我必须在内联汇编固有函数__asm__中使用字符串。我不确定编译器是否会接受一个const char[] - Ajay Brahmakshatriya
1
预处理器确实可以进行算术运算,例如 #if 2 + 2 == 4 是有效的。 - M.M
显示剩余8条评论

2
“是否可能使用宏执行算术运算(对于我的情况是乘法)?” 是的,根据您指定的限制(即您正在使用常量;特别是十进制字面值),并且有限制条件。链接的代码显示了一个ADD和一个MUL宏,可以做到这一点(它有点太大了,无法直接粘贴)。要使用预处理器宏本身执行此操作需要“实现算术运算”。此示例仅支持1到255之间的数字,并且需要您的C99兼容预处理器支持511个参数。点击此处查看更多信息。 Boost预处理器库还包含宏算术的实现;并且有支持DIV和SUB的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接