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

Inexecutable statements inside switch case

I have a segment of codes as follows. 'app' is a structure variable.

The code can successfully pass the compiling process and run but contains some inexecutable important commands, which can't be recognized by compiler, e.g.app.bT = TRUE. Besides, there are some disordered jump inside the switch, e.g. jumping from case 1 to case 5 without executing "break" in case 1.

app.bT=FALSE;

do {

switch ( ix )

{

case 0: if ( app.f0< app.fB1 ) app.bT = TRUE; break;

case 1: if (( app.fB1 <= app.f0 )&&( app.f0<= app.fB2 ) ) {if ( app.fC1 > ( ( app.fM1 * app.f0 ) +( app.f_Allowed - app.fM1* app.fB2 ) ) ) app.bT= TRUE; } break;

case 2: if ( app.f0>app.f_Allowed) app.bT = TRUE;

break;

case 3: if (( app.f0 <= app.fB4 ) ) { if ( app.fT > ( ( app.fM2 * app.f0 ) +( app.f_Allowed -app.fM2*app.fB3 ) ) ) app.bT = TRUE; } break;

case 4: if ( app.f0> app.fB4 ) app.bT = TRUE; break; default: break;

}

ix++;

}

while ( ix < 5 && app.bT == FALSE );

I think it's the internal error of C51 since there are few other explanation for this strange problem but I still don't want to believe that's true.
Would you please give me an answer? Thank you for your help.

  • Code is VERY difficult to read !

    Why not use the 'pre' tagging?

    Where is case 5 that you speak of?

  • Besides, there are some disordered jump inside the switch, e.g. jumping from case 1 to case 5 without executing "break" in case 1.

    This is most likely due to using a high optimization level when compiling. Turn off compiler optimizations and then check again.

  • "Why not use the 'pre' tagging?"

    As clearly described in the instructions: www.danlhenry.com/.../keil_code.png

  • I am sorry about that. I shortened the statements before I posted them out. There are totally 8 cases, ranging from case 0 to case 8. Inside the case, there are just some "if" statements just as I posted.

    I have tried the optimazation setting but it doesn't work at all. Also I have transplanted the entire "do switch" statements out to a single C file and compile it, but the same problem occured. So I am totally confused.

    Thank you for your help.

  • Post a minimal version of your code that fails so we can look.

    Please remember the 'pre' tags.

  • Thank you so much!!!!

    I followed your advice to reduce the optimazation level from 8 to 7 and the problem has been solved. But I can't believe why the default optimazation level is set 8, which may have a large potential to cause many problems.

  • "which may have a large potential to cause many problems"

    What actual problems have you seen?

    What you have described is perfectly normal behaviour for any optimised code - whether machine-optimised, or hand-crafted by a skilled assembler programmer.

    The "problems" you describe are merely (sic) in debugging - they should not affect the overall operation of the code...

  • I am sorry but I can't agree with you. I have run the program many times when the compiling was high optimized. Every time I ran and traced the execution of every statement inside the switch, some statements, e.g. app_bT=TRUE, could not be recognized as an executable while they should have been, besides there were disordered jumps between cases, e.g. from case1 to case 5, which I believe is absolutely wrong.

    What Christoph Franck told me is right. It is the problem with compiling optimization. When I reduce the optimization level by one, all the statements can be recognized and transformed into executable machine codes and ran normally.

  • You've missed the point!

    'C' does not guarantee that your source lines will be executed in sequence, step-by-step.

    eg, think about why the 'volatile' keyword exists...

    So long as the overall effect is the same, the program is operating correctly!

    Re-ordering instructions within case statements is a classic example of optimiser behaviour for any compiler;
    Similarly, combining common exit and entry code for functions;
    And deleting superfluous operations...

    If you just run the program with and without optimisation, and without trying to trace through it, can you actually tell the difference? If not, then there is no problem.
    If you can tell the difference, that is far more likely to be a flaw in your source than fault in the compiler!

  • "e.g. from case1 to case 5"

    If you want to discuss your code, please re-post it properly - I can't even see a case 5 in your original post!

  • No the source code has never been changed. When I increase the optimization level from 7 to 8, the problem occured again.

    I understand what you said about the 'volatile' and reordering, but I can tell you clearly that I have traced the execution of every statement step by step, and what I observed is that the execution sequence and result produced were totally different between two different optimization levels.

    Thank you for your concerns.

  • There are 8 cases inside the codes, but there are no big difference between statments inside those cases. So I just posted 4 with respect to efficiency. I am sorry about that.

    What I want to tell you is that, when the code contains complex statements with 'do while', 'switch' and 'if' statements inside, you should not set the code optimization level very high in order to prevent such errors.

  • "No the source code has never been changed."

    Of course not - optimisation does not affect the source code!
    Optimisation is performed on the Object code!

    "When I increase the optimization level from 7 to 8, the problem occured again."

    What problem?
    When you use high-level optimisations like this, you will never be able to simply follow the source lines in generated machine code - that's the whole point!
    An optimiser will always re-order code, remove unnecessary code, etc, etc to achieve its goal!
    That's what optimisers do!

    "I observed is that the execution sequence..."

    The execution sequence is irrelevant, and must be expected to change - see above.

    "...result produced were totally different"

    The final result, though, should be identical - aside from timing.

    If the final result is really different, then you most certainly do have a problem!
    In what way is the final result different?

  • Can you demostrate an actual error in the generated code? That is, post the source, and the generated assembler code, and point out where the result of executing the code is incorrect?

    Source level debuggers are often confused by highly optimizing compilers and may show you what appears to be strange execution as they hop from statement to statement. That does not mean the code is not producing the correct result.

    For example (and a completely invented one), the posted code has the statement "app.bT = TRUE" in many cases; the compiler might well choose to promote that statement into a more general block where it is always executed before entering some of the cases. So, if you put a breakpoint inside the case, you might not never see app.bT being set, as that happens before the breakpoint.

    If you can produce an example of the optimizer breaking things, then I'm sure Keil would appreciate it if you would email the example to support.

  • "are no big difference between statments inside those cases."

    Which is exactly the kind of thing that an optimiser will spot, and then it will re-order the code to avoid the duplication!

    " I just posted 4 with respect to efficiency"

    But what you posted was totally illegible, wasn't it?!

    "What I want to tell you is that ... you should not set the code optimization level very high in order to prevent such errors."

    That is misleading advice!

    You could justifiably say, as many have before, "if you want source-level debuginng, do not use high optimisation" - but to claim that the higher optimisation levels produce faulty code certainly needs some serious evidence!