协同程序的宏

时间:2014-11-16 12:45:07

标签: gcc c-preprocessor

我尝试用协同程序实现一些非常基本的多任务处理。目标平台是一个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是当前行号?或者我如何以不同的方式生成唯一标签?当然,我可以将所需的标签名称传递给宏,但我宁愿避免这种情况。

1 个答案:

答案 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__,我仍然会很高兴。