??? 06/10/11 11:30 Read: times |
#182576 - Skip the goto - almost always exists beautiful rewrites Responding to: ???'s previous message |
The only reason why you get multiple reads from the pin access (as required by the standard for volatile accesses) is that your code does multiple accesses.
Don't do a test, a goto and then a new test. Even more - don't do goto at all. Correct structuring would mean that you don't need any latching and don't need to see multiple reads of the volatile I/O pins. It's enough for your code to test it once, to figure out if the button is pressed or not. If you do check the pin twice in the C code, you just have to accept that the compiler produces two reads. The compiler have to fullfill the language standard. And it have to assume that you have two reads because you expect it to sometime change state between the two tests. Goto really is a bastard code construct. It can be nice to use in some _very_ few situations. Not for normal design flow, but as a way to have multiple exit points (a bit like "break" to have multiple ways out of a loop or a case statement. But having a goto that jumps backwards instead of jumping out of code really is a quadruply expensive/evil design because it is so hard to read the code and overview what will happen. If you find one use of goto every year, you are probably overusing goto. An example with goto (in the special case that goto is only forward-jumping as a replacement for C++ exceptions): x1 = do_something(); if (!x1) goto error; x2 = do_something_else(x1); if (!x2) goto error; if (!do_yet_another_thing()) goto error; ... // everything done. got a lucky ending. return TRUE; error: // Time for some garbage collect (poor mans C++ exceptions) cleanup(); return FALSE; } But such forward use of goto can be replaced with a dummy loop like: do { x1 = do_something(); if (!x1) break; x2 = do_something_else(x1); if (!x2) break; if (!do_yet_another_thing()) break; ... // everything done. got a lucky ending. return TRUE; } while (FALSE); // Time for some garbage collect (poor mans C++ exceptions) cleanup(); return FALSE; The reason why it may be hard to use a helper function instead, is of course that the code constructs above may require a lot of global variables or parameters if restructured into multiple functions instead of having actions and cleanup inside the same function. An option might be: struct helper_struct_t { int x1; int x2; ... }; int my_helper_function(helper_struct_t *info) { if (!info) return FALSE; info->x1 = do_something(); if (!info->x1) return FALSE; info->x2 = do_something_else(info->x1); if (!info->x2) return FALSE; if (!do_yet_another_thing()) return FALSE; ... // everything done. got a lucky ending. return TRUE; } helper_struct_t info; info.x1 = 0; info.x2 = 0; ... if (my_helper_function(&info)) { return TRUE; } else { cleanup(&info); return FALSE; } In the end, C is a language often connected with the saying "a minute to learn, a lifetime to master". Each keyword can be learned in a couple of minutes. But the big issue is how to combine them in a logical way that is clear and readable, while at the same time reasonably efficient regarding size and speed. goto is a keyword that can normally never be integrated into a program without big losses of readability. |
Topic | Author | Date |
Compiler variations?? | 01/01/70 00:00 | |
Fundamental philosophy of High-Level Languges (HLL) | 01/01/70 00:00 | |
C code | 01/01/70 00:00 | |
and so what | 01/01/70 00:00 | |
Stop wondering about the compiler output | 01/01/70 00:00 | |
Very nice to learn this important matter | 01/01/70 00:00 | |
Exactly what you wrote | 01/01/70 00:00 | |
volatile sbit may be the problem | 01/01/70 00:00 | |
read up on (not) volatile | 01/01/70 00:00 | |
Look at my profile | 01/01/70 00:00 | |
Not offence intended | 01/01/70 00:00 | |
defining P0_6 so that compiler doesn't treat it as volatile | 01/01/70 00:00 | |
Skip the goto - almost always exists beautiful rewrites | 01/01/70 00:00 | |
Goto really is a bastard code construct | 01/01/70 00:00 | |
and therefore ... | 01/01/70 00:00 | |
Will come back with modified code | 01/01/70 00:00 | |
Wonderful as always! | 01/01/70 00:00 |