This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

If-else chain not working properly.

Hi,

I am using nRF52840 DK, and I am creating my program starting from the basic UART example. I am not using threads, just plain sequential execution. I have a chain of if-else statements, like this:

if (condition1){
    //do something;
}else if (condition2){
    //do something else;
}else if (condition3){
    //do this;
}else if (condition4){
    //do that;
}else if (condition5){
    printf;
    call to function x;
}else{
    printf("no condition found");
}

The inputs fulfill condition5, but the code doesn't go into condition5. I have copied just above the code a simple if(condition5), and printf something, and it does go into that if statement, so condition5 is indeed fulfilled. I have also tried debugging step by step, and the execution jumps from the evaluation of if(condition4) to the last else directly, it doesn't even go into evaluating condition 5. If I change the order of the conditions and put condition5 first, it does work, but I need to add around 10 more conditions and the code would get quite messy if I don't put the conditions in any logical order.

I also know that it's better to use a switch, but in C I cannot do a switch of a string, so I am using an array and making conditions like if((command[0]==108)&(command[1]==101)&(command[2]==100)&(command_length==3))//led 

Any idea on how to handle this problem would be greatly appreciated. Thank you very much.

  • Hi,

     

    Is your array written from an interrupt context?

    I suspect that you need to declare the command[] array as volatile.

    Could you try this and report back?

     

    Best regards,

    Håkon

  • Hi,

    Thanks for the quick response.

    The array is declared in the main loop, and passed as a pointer to this function. What is quite bothering is that, if above all that, i put this:

    if(condition5){
        printf("found condition5");
    }

    It just works and executes the printf. And the first 4 conditions on the if-else chain work properly. That's why I discarded that there may be any issue in the declaration of condition5 or the access to the array command[].

    Also, condition1 is the one using more elements of the array command[] (7 elements), and that one does work properly, so I discarded that there may be any issue of access to the array.

    Finally, I have found a workaround by doing first the following:

    uint8_t index=0;
    for (uint8_t i=0; i<command_length; i++){
    	index += sprintf(&command_string[index], "%c", command[i]);
    }

    And then I have the info in a string, so I re-write the if conditions like this:

    if(strcmp(command_string, "led")==0){
        //do stuff
    }

    Now it works properly with all conditions.

    I don't know why it "likes" the string compare better, but for now I will go with it. If you want, I can try to declare the array as volatile and see what happens in the code that doesn't work properly, perhaps just to figure out why it was not working and to prevent similar things from happening in the future. One of my colleagues has the theory that it is an optimizer thing, and during compilation it "decides" that the fifth if will never happen, so it just blows it away. It makes sense, because when debugging that if statement is not implemented in the assembly code.

    Best regards,

    Alin O. Dragomir

  • It looks like the c syntax is incorrect. '&' is a bit-wise and, not the '&&' logical and that this test requires. Instead of this:

    if((command[0]==108)&(command[1]==101)&(command[2]==100)&(command_length==3))//led

    Try this:

    if((command[0]==108)&&(command[1]==101)&&(command[2]==100)&&(command_length==3))//led

    Then the original code may work better

  • You are right. I have edited the version of the code that still worked like that, replaced the & with &&, and it works. Thank you very much for your help.

Related