简体   繁体   English

CPP预处理程序到C预处理程序的转换问题

[英]CPP preprocessor to C preprocessor conversion question

edit: Title probably should be "Preprocessor, CPP compiler to C compiler conversion question. As I have been made aware, the preprocessors are the same. I looks to me like the issue is then that the result of the preprocessed code being compiled, CPP is happier with the layout compared to the C compiler. 编辑:标题可能应该是“预处理程序,从CPP编译器到C编译器的转换问题。正如我已经知道的,预处理程序是相同的。在我看来,问题是,正在编译的预处理代码的结果是CPP与C编译器相比,在布局上更快乐。

Any advice on how I can make this compatible into a C preprocessor? 关于如何使它兼容C预处理器的任何建议? I was trying to make a slick way of creating a flexible switch statement for a state machine that gets called on occasion and advances when specific criteria are met. 我试图以一种巧妙的方式为状态机创建灵活的switch语句,该语句有时会被调用,并且在满足特定条件时会前进。 Once it gets to the end of the switch statement it signals the state machine has completed by returning true. 一旦到达switch语句的末尾,它就通过返回true来指示状态机已完成。 I wanted to be able to swap/insert steps without having to re-assign case values , so this is what I came up with in CPP, which works really well. 我希望能够交换/插入步骤而不必重新分配案例值 ,所以这就是我在CPP中提出的,效果很好。

#include <iostream>
#include <thread>

#define DYNCOUNT(start) (__COUNTER__-start)

#define DYNAMIC_SWITCH_BEGIN(identifier,switchElement) \
    const unsigned int identifier = __COUNTER__; \
    switch(switchElement){ \
        case 0:

#define DYNAMIC_SWITCH_ELM(identifier) \
    break; \
    case DYNCOUNT(identifier):

#define DYNAMIC_SWITCH_END \
    break; \
    };


bool stateMachine(unsigned int & state) {

    DYNAMIC_SWITCH_BEGIN(ident, state)
        std::cout << "A" << std::endl;
    //if(some_condition){
    state++;
    //}
    DYNAMIC_SWITCH_ELM(ident)
        std::cout << "B" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM(ident)
        std::cout << "C" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM(ident)
        std::cout << "D" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM(ident)
        std::cout << "E" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM(ident)
        std::cout << "F" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM(ident)
        std::cout << "G" << std::endl;
    //if(some_condition){
    state++;
    //}
    break;
        default:
            return true;
            DYNAMIC_SWITCH_END

                return false;
                //Visual Studios gets confused with the layout and structures it with this tabulation. 
}

int main() {

    unsigned int machineState=0;
    while(!stateMachine(machineState)){/*other operations*/}

    std::this_thread::sleep_for(std::chrono::seconds(5));
    return 0;
}

However when I try to run it in a C environment through MPLAB I get: 但是,当我尝试通过MPLAB在C环境中运行它时,会得到:

stateMachines.c:28:9: error: case label does not reduce to an integer constant DYNAMIC_SWITCH_ELM(ident) stateMachines.c:28:9:错误:案例标签未减少为整数常量DYNAMIC_SWITCH_ELM(ident)

So it appears that the CPP preprocessor is willing to interpret a const unsigned int value into its commands while the C preprocessor, or at least MPLAB's C preprocessor, does not. 因此,似乎CPP预处理器愿意将const unsigned int值解释为其命令,而C预处理器或至少MPLAB的C预处理器则不这样做。

My only alternative is to trim out some of the content of the DYNAMIC_SWITCH_BEGIN call and instead place a 我唯一的选择是删除DYNAMIC_SWITCH_BEGIN调用的某些内容,而是放置一个

#define ident __COUNT__ 

at the beginning of the switch. 在切换开始时。 Which works too, but I was trying to get a more enforced structure layout. 这也可行,但是我试图获得更强制的结构布局。

Credit to @EricPostpischil for leading me to this solution. 感谢@EricPostpischil将我引向这个解决方案。 The switch will behave as if it starts at 0 even though the case values are adjusting. 即使大小写值正在调整,该开关也将表现为从0开始。 Since it is behind the scenes it doesn't really matter that the case value doesn't start with 0. 由于它在幕后,所以case值不以0开头并不重要。

#include <iostream>
#include <thread>

#define DYNCOUNT(start) (__COUNTER__-start)

#define DYNAMIC_SWITCH_BEGIN(switchElement) \
    switch((switchElement + (__COUNTER__+1))){ \
        case __COUNTER__:

#define DYNAMIC_SWITCH_ELM \
    break; \
    case __COUNTER__:

#define DYNAMIC_SWITCH_END \
    break; \
    };


bool stateMachine(unsigned int & state) {

    DYNAMIC_SWITCH_BEGIN(state)
        std::cout << "A" << std::endl;
    //if(some_condition){
    state++;
    //}
    DYNAMIC_SWITCH_ELM
        std::cout << "B" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "C" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "D" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "E" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "F" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "G" << std::endl;
    //if(some_condition){
    state++;
    //}
    break;
        default:
            return true;
            DYNAMIC_SWITCH_END

                return false;
}

bool stateMachine_2(unsigned int & state) {

    DYNAMIC_SWITCH_BEGIN(state)
        std::cout << "H" << std::endl;
    //if(some_condition){
    state++;
    //}
    DYNAMIC_SWITCH_ELM
        std::cout << "I" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "J" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "K" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "L" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "M" << std::endl;
    //if(some_condition){
    state++;
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "N" << std::endl;
    //if(some_condition){
    state++;
    //}
    break;
        default:
            return true;
            DYNAMIC_SWITCH_END

                return false;
}

int main() {

    unsigned int machineState=0;
    while(!stateMachine(machineState)){}
    machineState = 0;
    while (!stateMachine_2(machineState)) {}

    std::this_thread::sleep_for(std::chrono::seconds(5));
    return 0;
}

Edit: 编辑:

For anybody intesrested, I added some additional useful tools to my original code so it could be used for not only a step-wise advancing state machine but also contain loop-backs or jump forwards in case the state machine is more advanced. 对于所有感兴趣的人,我在原始代码中添加了一些其他有用的工具,因此它不仅可以用于逐步推进的状态机,还可以包含环回或向前跳转(以防状态机更高级)。 Still allows to just copy and paste or insert items wherever desired, keeping with the goal. 仍然可以根据需要仅复制和粘贴或插入项目。

#define DYNAMIC_SWITCH_BEGIN(elementType,switchElement) \
    do{ \
    const elementType DYNAMIC_SWITCH_OFFSET=__COUNTER__+1; \
    elementType * __DYNAMIC_SWITCH_MODIFY_TARGET = & switchElement; \
    int __DYNAMIC_JUMP_FLAG=0; \
    switch((switchElement + DYNAMIC_SWITCH_OFFSET)){ \
        case __COUNTER__:

#define DYNAMIC_SWITCH_ELM \
    break; \
    case __COUNTER__:

#define DYNAMIC_ADV (*__DYNAMIC_SWITCH_MODIFY_TARGET)++;

#define DYNAMIC_SWITCH_DFLT \
    break; \
    default:

#define DYNAMIC_SWITCH_JUMP(jumpTag) \
    __DYNAMIC_JUMP_FLAG=1; \
    goto jumpTag;

#define DYNAMIC_SWITCH_TAGGED_ELM(jumpTag) \
    break; \
    case __COUNTER__: \
    case (__COUNTER__ +1): \
    jumpTag: \
    (*__DYNAMIC_SWITCH_MODIFY_TARGET) = __COUNTER__ - DYNAMIC_SWITCH_OFFSET; \
    if(__DYNAMIC_JUMP_FLAG)break; //Force to exit and complete on next loop for consistency in stepping behavior.

#define DYNAMIC_SWITCH_END \
    break; \
    }; \
    }while(0);

bool stateMachine(unsigned int & state) {

    DYNAMIC_SWITCH_BEGIN(unsigned int, state)
        std::cout << "A" << std::endl;
    //if(some_condition){
    DYNAMIC_ADV
    //}
    DYNAMIC_SWITCH_ELM
        std::cout << "B" << std::endl;
    //if(some_condition){
    DYNAMIC_ADV
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "C" << std::endl;
    //if(some_condition){
    DYNAMIC_ADV
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "D" << std::endl;
    //if(some_condition){
    DYNAMIC_ADV
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "E" << std::endl;
    //if(some_condition){
    DYNAMIC_ADV
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "F" << std::endl;
    DYNAMIC_SWITCH_JUMP(tag1)
    //if(some_condition){
    DYNAMIC_ADV
    //}

    DYNAMIC_SWITCH_ELM
        std::cout << "G" << std::endl;
    //if(some_condition){
    DYNAMIC_ADV
    //}
    DYNAMIC_SWITCH_TAGGED_ELM(tag1)
        std::cout << "H" << std::endl;
    DYNAMIC_ADV

    DYNAMIC_SWITCH_ELM
        std::cout << "I" << std::endl << std::endl;;
    //if(some_condition){
    DYNAMIC_ADV

    DYNAMIC_SWITCH_DFLT
        return true;
    DYNAMIC_SWITCH_END
        return false;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM