首页 > 解决方案 > 在 C 中,您可以将具有多个值的宏传递给函数吗

问题描述

我有一个消息传递函数,它接受可变数量的参数,因为它以与 printf 相同的方式支持字符串格式化。然后我的计划是用一个单一的定义消息代码和消息,#define并能够通过传递一个与紧密相关的东西的单个参数来调用这个函数。

这是消息宏:

#define MSG(a, b, ...) message(__FILE__, __LINE__, a, b, __VA_ARGS__);

这是消息代码和字符串定义的示例:

#define MSG_INIT 0000,"%s INITIALIZED SUCCESSFULLY"

当我尝试以以下形式拨打电话时,会出现此问题:

MSG(MSG_INIT);

我的 IDE 给了我一个错误,如下所示:

'Expands to message("file.c", 1, 0000, "INITIALIZED SUCCESSFULLY",);

最后一个','导致问题的地方。

我期待看到:

'Expands to message("file.c", 1, 0000, "INITIALIZED SUCCESSFULLY");

如果我将呼叫更改为:

MSG(MSG_INIT,NULL);

一切都很好,但我宁愿不传递 NULL,因为MSG_INIT首先定义的目的是传递更少的参数。有些消息使用了__VA_ARGS__(例如:#define MSG_CONNECT 0001,"CONNECTION TO [%s] ESTABLISHED"使用匹配的 call MSG(MSG_CONEST, server_ip);),因此摆脱它不是一种选择。我只是在寻找解决此问题的最佳方法,并且我知道很多人建议远离预处理器,但这是我想到的最佳解决方案。

标签: macrosc-preprocessor

解决方案


我知道很多人建议远离预处理器......

我不知道这是为什么。可能出于同样的原因你不得不问这个问题吗?:-)

老实说,预处理器应该仅限于包含头文件和进行条件编译。它曾经用于的任何其他东西,例如:

#define RC_OK    0
#define RC_NOMEM 1

#define HALF_OF(x) x / 2

使用枚举或函数做得更好。

类似函数的宏的时代应该被抛在脑后,特别是因为现代编译器可以很容易地优化大多数手工编写的代码,并且不会HALF_OF像上面的那个宏那样出现细微的错误(不要使用它,我专门做了说明一点是错误的)。

它实际上只是一个文本替换的东西,它理解词汇元素,但不是 C 的完整语法。事实上,你必须执行我所说的“宏观体操”才能让它做除了简单的事情之外的任何事情,这就是足够的理由避开。为此使用功能,它会让你的生活更轻松。


并且很抱歉没有解决您的具体问题,我只是认为使用预处理器的任何解决方案充其量都是半生不熟的。但是在回答“IX 怎么做?”这个问题时,有很多关于 SO 的先例。用“不要X,最好是Y。” 想想用汇编程序编写会计包,用面向对象的 COBOL 编写操作系统,或者用 Pascal 编写任何东西:-)

但是,如果您真的想按照我的建议坚持使用宏,您可以尝试从以下内容开始:

#include <stdio.h>

#define MSG(fmtStr, ...) printf("%s:%d> " fmtStr, __FILE__, __LINE__, __VA_ARGS__)
#define MSG_INIT "Initialised %s\n"
#define MSG_TERM "Terminated %s with values %d and %d\n"

int main(void) {
    MSG("%f\n", 42.3);
    MSG(MSG_INIT, "something");
    MSG(MSG_TERM, "something else", 7, 42);
}

认为这是可移植的,它允许您将繁重的工作放入MSG并为其余内容使用单独的格式字符串和参数:

testprog.c:8> 42.300000
testprog.c:9> Initialised something
testprog.c:10> Terminated something else with values 7 and 42

推荐阅读