我有一个嵌入式操作系统,需要通过编译时间静态定义其资源。
所以,例如。
#define NUM_TASKS 200
目前,我有一个头文件,每个开发人员都需要声明他/她需要的任务,有点像这样:
#define ALL_TASKS ( \
1 + \ /* need one task in module A */
2 \ /* need two tasks in module B */
)
在编译操作系统期间,有一个检查:
#if (ALL_TASKS > NUM_TASKS)
#error Please increase NUM_TASKS in CONF.H
#endif
因此,当我编译并需要更多任务时,编译停止并明确通知静态操作系统将没有足够的任务来使其工作。
到目前为止一切顺利。
输入懒惰的程序员,忘记将他在模块A中添加的任务添加到目录x / y / z / foo / bar / baz /中的全局声明文件中。
我想要的是以下构造,我尝试的任何宏观技巧似乎无法实现:
让宏声明模块中所需的资源,如下所示:
OS_RESERVE_NUMBER_OF_TASKS(2)
模块中的将全局任务数加2。
我的第一个粗略想法是这样的:
#define OS_RESERVE_NUMBER_OF_TASKS(max_tasks) #undef RESOURCE_CALC_TEMP_MAX_NUM_TASKS \
#define RESOURCE_CALC_TEMP_MAX_NUM_TASKS RESOURCE_CALC_MAX_NUM_TASKS + max_tasks \
#undef RESOURCE_CALC_MAX_NUM_TASKS \
#define RESOURCE_CALC_MAX_NUM_TASKS RESOURCE_CALC_TEMP_MAX_NUM_TASKS \
#undef RESOURCE_CALC_TEMP_MAX_NUM_TASKS
但这不起作用,因为#define
中的#define
不起作用。
所以问题基本上是:
您是否知道如何将任务数量的计算分成多个文件(即模块本身),并在编译期间将该数字编入到定义的最大任务数中?
如果使用纯C预处理器无法解决这个问题,我将不得不等到我们将make系统更改为scons ...
答案 0 :(得分:3)
您是否可以要求所有任务用户必须使用某些ID或类似的任务?
<强> tasks.h 强>
enum {
TASK_ID_TASK_A_1,
TASK_ID_TASK_B_1,
TASK_ID_TASK_B_2,
NUM_TASKS
};
void * giveResource(int taskId, int resourceId);
<强> user_module_B.c 强>
#include "tasks.h"
...
resource = giveResource(TASK_ID_TASK_B_1, resource_id_B_needs);
答案 1 :(得分:1)
您可以使用Boost预处理器库evaluated slots functionality在翻译一个单元的过程中更新宏的值。它定义了几个&#34;插槽&#34;可以通过预处理器代码将其视为可变全局变量,这可以让您在进行时添加值,而不是使用单个表达式定义它。
(它是纯粹的标准C,但实现它的代码相当复杂)
你不能在一行中完成它,因为它依赖于对#include
的调用,这意味着你无法将它包装成漂亮的单行宏,但它会看起来像这样:
#define TASK_SLOT 2 //just pick one
#define ALL_TASKS BOOST_PP_SLOT(TASK_SLOT)
#define BOOST_PP_VALUE 1 + 2
#include BOOST_PP_ASSIGN_SLOT(TASK_SLOT) // ALL_TASKS now evals to 3
#define BOOST_PP_VALUE 3 + ALL_TASKS
#include BOOST_PP_ASSIGN_SLOT(TASK_SLOT) // ALL_TASKS now evals to 6
由于Drew评论(我可能误解了您的要求),这仅对一个翻译单元有效。如果您有一个核心NUM_TASKS
,并且每个单元都可以添加其自己的 ALL_TASKS
数字,那么这很好。
如果您需要在多个.c文件中递增值(以便最终ALL_TASKS
是所有模块的总和,而不是一个),您需要将它们包装成{ {3}}这种技术起作用,大多数人认为这是一个坏主意。然后,更高级的构建系统可能是合适的,因为预处理器仅设计用于单个单元。