为宏强制未使用的参数
force unused parameter for macro
简单的想法:
我正在使用 X-macros 来定义命令列表结构并声明命令回调。
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#define COMMAND_LIST(X) \
X(toto_all) \
X(help) \
//end of list
typedef void (*callback_t)(int a, int b);
typedef struct
{
char * name;
callback_t callback;
}command_t;
#define CALLBACK_DEC(COMMAND_NAME) void _##COMMAND_NAME(int a, int b);
COMMAND_LIST(CALLBACK_DEC)
#define COMMAND_DEF(COMMAND_NAME) { #COMMAND_NAME, & _##COMMAND_NAME },
static command_t commands[] =
{
COMMAND_LIST(COMMAND_DEF)
};
#define COMMAND(COMMAND_NAME,CODE) void _##COMMAND_NAME(int A, int B) { CODE }
COMMAND(toto_all,
printf("helloworld\n");
)
COMMAND(help,
printf("help!\n");
)
int main()
{
commands[0].callback(1,2);
commands[1].callback(1,2);
return 0;
}
有效。
helloworld
help!
添加一些参数:
如果将第一个命令列表改成这个(通过添加参数)
#define COMMAND_LIST(X) \
X(toto_all, 1, 3, 5) \
X(help, 0, 0, 0) \
//end of list
typedef struct
{
callback_t callback;
char * name;
int arg_min;
int arg_max;
int arg_num;
}command_t;
然后,当 运行 它出现以下错误时:
macro "CALLBACK_DEC" passed 4 arguments, but takes just 1
我必须使用命令列表定义(命令声明)的所有参数:
#define COMMAND_DEF(COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_MAX, ARG_NUM) (command_t){ #COMMAND_NAME, & _##COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM},
但现在将其用于回调声明非常棘手...
这个X-macro有什么巧妙的方法可以避免这个错误吗?
我想到了屏蔽未使用参数的非宏方法:
这是通过使用(void)param;
,
这给了丑陋的
#define CALLBACK_DEC(COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM) void _##COMMAND_NAME(int a, int b); void(ARG_MIN); void(ARG_MAX); void(ARG_NUM)
这行不通...我觉得很奇怪:
main.c:27:20: error: expected identifier or ‘(’ before numeric constant
X(toto_all,0,0,0) \
我觉得还有一个办法:
也许使用类似这样的东西...
#define COMMAND_LIST(X,Y) \
X(Y(toto_all, 0, 0, 0)) \
X(Y(help, 0, 0, 0)) \
//command name, arg min, arg max, arg num, string?
//end of list
typedef void (*callback_t)(int a, int b);
typedef struct
{
char * name;
callback_t callback;
}command_t;
#define GET_ONLY_NAME(COMMAND_NAME1, ARG_MIN, ARG_MAX, ARG_NUM) COMMAND_NAME1
#define CALLBACK_DEC(COMMAND_NAME) void _##COMMAND_NAME(int a, int b);
COMMAND_LIST(CALLBACK_DEC,GET_ONLY_NAME);
#undef CALLBACK_DEC
#define GET_FULL_LIST(X) X
#define COMMAND_DEF(COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM) (command_t){ #COMMAND_NAME, & _##COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM},
static command_t commands[] =
{
COMMAND_LIST(COMMAND_DEF,GET_FULL_LIST)
};
#undef COMMAND_DEF
但我仍然得到以下奇怪的错误,扩展中有问题但我看不到哪里...
main.c:27:31: error: expected ‘)’ before numeric constant
X(Y(toto_all, 0, 0, 0)) \
也许真相在别处……:)
有什么提示吗?
这是 X 宏总体上的一个问题 - 您必须编写一个接受所有参数的宏,即使您只使用几个参数也是如此。
在您的情况下,您将特定的宏作为参数传递给列表,因此您可以在其中增加一些灵活性。使用可变参数宏可能会解决问题。你应该可以这样做:
#define COMMAND_DEF(COMMAND_NAME, ...) { #COMMAND_NAME, & _##COMMAND_NAME },
...
COMMAND_LIST(COMMAND_DEF)
你只明确命名这个特定宏感兴趣的参数,然后让其余参数进入 ...
部分,然后被忽略。
然而,这确实在数据中建立了依赖关系,因为它只允许您从左到右扩展参数,可以这么说。所以对于
X(toto_all, 1, 3, 5, "-")
您可以编写仅使用 toto_all
或 toto_all
和 1
的宏,但您无法编写仅使用例如 [=16] 的宏=] 和 3
。对于这种特殊情况,我相信您仍然必须命名所有宏参数。
另一种选择是自文档化代码:
#define COMMAND_DEF(COMMAND_NAME, ignored1, FOO, ignored2, ignored3) \
/* do stuff with COMMAND NAME and FOO only */
简单的想法:
我正在使用 X-macros 来定义命令列表结构并声明命令回调。
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#define COMMAND_LIST(X) \
X(toto_all) \
X(help) \
//end of list
typedef void (*callback_t)(int a, int b);
typedef struct
{
char * name;
callback_t callback;
}command_t;
#define CALLBACK_DEC(COMMAND_NAME) void _##COMMAND_NAME(int a, int b);
COMMAND_LIST(CALLBACK_DEC)
#define COMMAND_DEF(COMMAND_NAME) { #COMMAND_NAME, & _##COMMAND_NAME },
static command_t commands[] =
{
COMMAND_LIST(COMMAND_DEF)
};
#define COMMAND(COMMAND_NAME,CODE) void _##COMMAND_NAME(int A, int B) { CODE }
COMMAND(toto_all,
printf("helloworld\n");
)
COMMAND(help,
printf("help!\n");
)
int main()
{
commands[0].callback(1,2);
commands[1].callback(1,2);
return 0;
}
有效。
helloworld
help!
添加一些参数:
如果将第一个命令列表改成这个(通过添加参数)
#define COMMAND_LIST(X) \
X(toto_all, 1, 3, 5) \
X(help, 0, 0, 0) \
//end of list
typedef struct
{
callback_t callback;
char * name;
int arg_min;
int arg_max;
int arg_num;
}command_t;
然后,当 运行 它出现以下错误时:
macro "CALLBACK_DEC" passed 4 arguments, but takes just 1
我必须使用命令列表定义(命令声明)的所有参数:
#define COMMAND_DEF(COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_MAX, ARG_NUM) (command_t){ #COMMAND_NAME, & _##COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM},
但现在将其用于回调声明非常棘手...
这个X-macro有什么巧妙的方法可以避免这个错误吗?
我想到了屏蔽未使用参数的非宏方法:
这是通过使用(void)param;
,
这给了丑陋的
#define CALLBACK_DEC(COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM) void _##COMMAND_NAME(int a, int b); void(ARG_MIN); void(ARG_MAX); void(ARG_NUM)
这行不通...我觉得很奇怪:
main.c:27:20: error: expected identifier or ‘(’ before numeric constant
X(toto_all,0,0,0) \
我觉得还有一个办法:
也许使用类似这样的东西...
#define COMMAND_LIST(X,Y) \
X(Y(toto_all, 0, 0, 0)) \
X(Y(help, 0, 0, 0)) \
//command name, arg min, arg max, arg num, string?
//end of list
typedef void (*callback_t)(int a, int b);
typedef struct
{
char * name;
callback_t callback;
}command_t;
#define GET_ONLY_NAME(COMMAND_NAME1, ARG_MIN, ARG_MAX, ARG_NUM) COMMAND_NAME1
#define CALLBACK_DEC(COMMAND_NAME) void _##COMMAND_NAME(int a, int b);
COMMAND_LIST(CALLBACK_DEC,GET_ONLY_NAME);
#undef CALLBACK_DEC
#define GET_FULL_LIST(X) X
#define COMMAND_DEF(COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM) (command_t){ #COMMAND_NAME, & _##COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM},
static command_t commands[] =
{
COMMAND_LIST(COMMAND_DEF,GET_FULL_LIST)
};
#undef COMMAND_DEF
但我仍然得到以下奇怪的错误,扩展中有问题但我看不到哪里...
main.c:27:31: error: expected ‘)’ before numeric constant
X(Y(toto_all, 0, 0, 0)) \
也许真相在别处……:)
有什么提示吗?
这是 X 宏总体上的一个问题 - 您必须编写一个接受所有参数的宏,即使您只使用几个参数也是如此。
在您的情况下,您将特定的宏作为参数传递给列表,因此您可以在其中增加一些灵活性。使用可变参数宏可能会解决问题。你应该可以这样做:
#define COMMAND_DEF(COMMAND_NAME, ...) { #COMMAND_NAME, & _##COMMAND_NAME },
...
COMMAND_LIST(COMMAND_DEF)
你只明确命名这个特定宏感兴趣的参数,然后让其余参数进入 ...
部分,然后被忽略。
然而,这确实在数据中建立了依赖关系,因为它只允许您从左到右扩展参数,可以这么说。所以对于
X(toto_all, 1, 3, 5, "-")
您可以编写仅使用 toto_all
或 toto_all
和 1
的宏,但您无法编写仅使用例如 [=16] 的宏=] 和 3
。对于这种特殊情况,我相信您仍然必须命名所有宏参数。
另一种选择是自文档化代码:
#define COMMAND_DEF(COMMAND_NAME, ignored1, FOO, ignored2, ignored3) \
/* do stuff with COMMAND NAME and FOO only */