Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
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.

List of 17 messages in thread
TopicAuthorDate
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      

Back to Subject List