我尝试用协同程序实现一些非常基本的多任务处理。目标平台是一个AVR微控制器,所以我的内存很紧张,不能做很多花哨的东西。我在这里描述的想法在这里描述:Coroutines in C (Simon Tatham)
但是这种方法使用switch语句和static gotos。我更喜欢计算得到的。因此,我提出了以下一段代码。
void static_parse(const char c) {
static void * parser_state = &&l_parser_start;
goto *parser_state;
#define WAIT_FOR_NEXT_CHAR parser_state = &&label ## __LINE__ ; return; label ## __LINE__ : ;
l_parser_start:
// do some stuff with first character
WAIT_FOR_NEXT_CHARACTER;
// do some stuff with second character
WAIT_FOR_NEXT_CHARACTER;
// do some stuff with third character
l_done:
parser_state = &&l_parser_start;
return;
我的想法是提取标签的地址并将其保存在静态变量中。每当有新的charcater可用时,调用者负责将角色推送到该协程。不幸的是,这不起作用。编译器抱怨
test.cpp:73:1: error: duplicate label ‘label__LINE__’
test.cpp:76:1: error: duplicate label ‘label__LINE__’
显然,在__LINE__
宏的帮助下获取不同标签的想法失败了,因为__LINE__
没有得到扩展。我尝试了不同的预处理技巧,但到目前为止每次尝试都失败了。
另一次不成功的尝试是
static void * parser_state = &&l_parser_start;
goto *parser_state;
#define INNER(N) parser_state = &&label ## N ; return; label ## N : ;
#define WAIT_FOR_NEXT_CHAR INNER(__LINE__)
l_parser_start:
如何生成看起来像label_nnnn的标签,其中nnnn是当前行号?或者我如何以不同的方式生成唯一标签?当然,我可以将所需的标签名称传递给宏,但我宁愿避免这种情况。
答案 0 :(得分:1)
到目前为止我找到了一个解决方案
static void * parser_state = &&l_parser_start;
goto *parser_state;
#define LABEL(N) label_ ## N
#define XLABEL(N) LABEL(N)
#define WAIT_FOR_NEXT_CHAR parser_state = &&XLABEL(__LINE__) ; return; XLABEL(__LINE__) : ;
l_parser_start: ;
解决方案基本上是Argument Prescan文档的副本。但是我没有真正的线索为什么其他尝试失败了。所以,如果有人可以解释为什么其他宏不像我预期的那样扩展__LINE__
,我仍然会很高兴。