This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Parts of code are ignored by compiler, can't put breakpoint on these parts

Hello,

I have a problem in my program, At execution in debug mode the code I wrote is just ignored.

The code is a system filtering message and checking validity of data received, I use switch case and imbricated switch case to filter the message and if else condition to validate the data.

It seems that else case and default case are sometime ignored but not always!

Break condition are also ignored in certain case.

The compilation process don't say anything about the code wrote.

the problem occur in imbricated switch case.

Have you an idea of what can be the problem?

Here my code:


case APP_SERVICE_CAN__MAINTENANCE_DATE:
switch(pdata[SDOSUBINDEX])
{

case LAST_MAINTENANCE_DATE:
if( isCANFormatDate(sdo_data.Word32bit))
{
eeprom_write_Last_Maintenance_date(sdo_data.Word32bit);
}
else {status = USERSDO_ABORT;}//can't put breakpoint here --> this part is ignored
break;

case NEXT_MAINTENANCE_DATE:
if( isCANFormatDate(sdo_data.Word32bit))
{
eeprom_write_Next_maintenance_date(sdo_data.Word32bit);
}else{
status = USERSDO_ABORT;//can't put breakpoint here
}
break;
default:
status = USERSDO_ABORT;// can't put break point here
break;
}
break;// can't put breakpoint here

I know the compiler optimize the code and ignore the dead part but all of these cases are reachable (I think), I heard about use of #pragma to change locally the compiler behavior but I don't know if it's the real problem here.

I also read about the way compiler interpret the switch case, it can be a series of if elsif or a jump list depending of various criteria. this variable judgement of compiler is maybe the problem.

So I hesitate to rewrite the code in a different way, have you known issue like that?

thank for answers,
Guillaume

Parents
  • Note that tab characters doesn't work well when posting source code - it's just arbitrary whitespace outside of your editor.

        ##### you should have let us see the full set of code
        ##### instead of a sub-section of a switch statement.
    
        case APP_SERVICE_CAN__MAINTENANCE_DATE:
            switch(pdata[SDOSUBINDEX]) {
                case LAST_MAINTENANCE_DATE:
                    if( isCANFormatDate(sdo_data.Word32bit)) {
                        eeprom_write_Last_Maintenance_date(sdo_data.Word32bit);
                    } else {
                        status = USERSDO_ABORT;
                    }//can't put breakpoint here --> this part is ignored
                    break;
    
                case NEXT_MAINTENANCE_DATE:
                    if( isCANFormatDate(sdo_data.Word32bit)) {
                        eeprom_write_Next_maintenance_date(sdo_data.Word32bit);
                    } else {
                        status = USERSDO_ABORT;//can't put breakpoint here
                    }
                    break;
    
                default:
                    status = USERSDO_ABORT;// can't put break point here
                    break;
            }
            break;// can't put breakpoint here
    


    As you can see, my reindenting of the code did not keep your end-of-line comments at their original location since end-of-line c++ comments "pointing" at code depends on viewing the code with the correct line breaks as the code was originally written...

    Which is why it's important that what you see when you post must be the same as what you see in your editor.

    Anyway.

    Let's look at the first break in your code fragment.
    It would be stupid of the compiler to create two jumps after each other.
    First a jump just to get out if the if/else part to reach the "break". Then second jump in the form of the "break".
    So the compiler will produce code taht jumps out of the switch as soon as it comes to the } of either the "if" or the "else" block without first visiting your "break" statement.

    And since no code path of your nested switch does fall through - all parts we see has a "break", then your code is always break followed by break.

    No reason for the compiler to have the first break go to the second break and then jump one step further to leave the outer switch. So the compiler will make all break of the nested switch jump out of both levels of switch. To avoid that, you need a statement after the nested switch ends, but before the break. Like this:

    switch (outer_condition) {
        case xxx:
            switch (nested_condition) {
                case a:
                    do_something();
                    break;
                case b:
                    do_something_else();
                default:
                    do_yet_another_thing();
            }
            extra_action_before_break_out_of_outer_switch();
            break;
        ...
    } // switch
    

    Now the compiler will no longer see one break jump to a new break so the inner break will not leave two levels of switch statements.

    But notice that a break is never a good statement to try to put a breakpoint on since the compiler quite seldom will insert an explicit jump instruction where you write your break. A break represents flow control. And flow control is one of the main things the compiler optimizer spends quite some time trying to improve. Both to improve speed and to improve code size.

Reply
  • Note that tab characters doesn't work well when posting source code - it's just arbitrary whitespace outside of your editor.

        ##### you should have let us see the full set of code
        ##### instead of a sub-section of a switch statement.
    
        case APP_SERVICE_CAN__MAINTENANCE_DATE:
            switch(pdata[SDOSUBINDEX]) {
                case LAST_MAINTENANCE_DATE:
                    if( isCANFormatDate(sdo_data.Word32bit)) {
                        eeprom_write_Last_Maintenance_date(sdo_data.Word32bit);
                    } else {
                        status = USERSDO_ABORT;
                    }//can't put breakpoint here --> this part is ignored
                    break;
    
                case NEXT_MAINTENANCE_DATE:
                    if( isCANFormatDate(sdo_data.Word32bit)) {
                        eeprom_write_Next_maintenance_date(sdo_data.Word32bit);
                    } else {
                        status = USERSDO_ABORT;//can't put breakpoint here
                    }
                    break;
    
                default:
                    status = USERSDO_ABORT;// can't put break point here
                    break;
            }
            break;// can't put breakpoint here
    


    As you can see, my reindenting of the code did not keep your end-of-line comments at their original location since end-of-line c++ comments "pointing" at code depends on viewing the code with the correct line breaks as the code was originally written...

    Which is why it's important that what you see when you post must be the same as what you see in your editor.

    Anyway.

    Let's look at the first break in your code fragment.
    It would be stupid of the compiler to create two jumps after each other.
    First a jump just to get out if the if/else part to reach the "break". Then second jump in the form of the "break".
    So the compiler will produce code taht jumps out of the switch as soon as it comes to the } of either the "if" or the "else" block without first visiting your "break" statement.

    And since no code path of your nested switch does fall through - all parts we see has a "break", then your code is always break followed by break.

    No reason for the compiler to have the first break go to the second break and then jump one step further to leave the outer switch. So the compiler will make all break of the nested switch jump out of both levels of switch. To avoid that, you need a statement after the nested switch ends, but before the break. Like this:

    switch (outer_condition) {
        case xxx:
            switch (nested_condition) {
                case a:
                    do_something();
                    break;
                case b:
                    do_something_else();
                default:
                    do_yet_another_thing();
            }
            extra_action_before_break_out_of_outer_switch();
            break;
        ...
    } // switch
    

    Now the compiler will no longer see one break jump to a new break so the inner break will not leave two levels of switch statements.

    But notice that a break is never a good statement to try to put a breakpoint on since the compiler quite seldom will insert an explicit jump instruction where you write your break. A break represents flow control. And flow control is one of the main things the compiler optimizer spends quite some time trying to improve. Both to improve speed and to improve code size.

Children
No data