do{switch(0)default:{/*break or continue*/;}/*cleanup*/}while(0);

Discussion in 'C Programming' started by Francois Grieu, Jul 22, 2011.

  1. I just came into a case where I could use this:

    do
    {
    // local declarations and initializations
    switch(0)default:
    {
    // bunch of if/else; within that:
    // - "break" performs cleanup;
    // - "continue" skips cleanup.
    /*..*/;
    }
    /*..*/; // cleanup
    }
    while(0);


    [Notes: This is 'only' a way to avoid gotos. It places
    restrictions on the use of other do/while/for/switch.
    The second brace could be before default, but I find
    the dummy switch idiom more recognizable that way.]


    I'm looking for a classical reference on that construct,
    like there is one for
    <http://www.lysator.liu.se/c/duffs-device.html>


    Or perhaps one for the similar:

    do
    {
    // local declarations and initializations
    switch(condition)
    {
    // leaving is done
    // - "break" performs cleanup;
    // - "continue" skips cleanup.
    case 0:
    /*..*/;
    case 1:
    /*..*/;
    ;
    }
    /*..*/; // cleanup
    }
    while(0);



    TIA,

    Francois Grieu
    Francois Grieu, Jul 22, 2011
    #1
    1. Advertising

  2. On Jul 22, 8:49 am, Francois Grieu <> wrote:
    > I just came into a case where I could use this:
    >
    >    do
    >    {
    >    // local declarations and initializations
    >      switch(0)default:
    >      {
    >      // bunch of if/else; within that:
    >      // - "break" performs cleanup;
    >      // - "continue" skips cleanup.
    >      /*..*/;
    >      }
    >    /*..*/; // cleanup
    >    }
    >    while(0);
    >
    > [Notes: This is 'only' a way to avoid gotos. It places
    > restrictions on the use of other do/while/for/switch.
    > The second brace could be before default, but I find
    > the dummy switch idiom more recognizable that way.]
    >
    > I'm looking for a classical reference on that construct,
    > like there is one for
    > <http://www.lysator.liu.se/c/duffs-device.html>
    >
    > Or perhaps one for the similar:
    >
    >    do
    >    {
    >    // local declarations and initializations
    >      switch(condition)
    >      {
    >      // leaving is done
    >      // - "break" performs cleanup;
    >      // - "continue" skips cleanup.
    >      case 0:
    >        /*..*/;
    >      case 1:
    >        /*..*/;
    >        ;
    >      }
    >    /*..*/; // cleanup
    >    }
    >    while(0);
    >
    > TIA,
    >
    >    Francois Grieu


    I think the correct term is ''kludge'' and, frankly, i prefer gotos to
    misappropriating break and continue keywords. But that's just my POV.
    Kleuskes & Moos, Jul 22, 2011
    #2
    1. Advertising

  3. Francois Grieu

    gwowen Guest

    On Jul 22, 7:49 am, Francois Grieu <> wrote:

    > [Notes: This is 'only' a way to avoid gotos. It places
    > restrictions on the use of other do/while/for/switch.
    > The second brace could be before default, but I find
    > the dummy switch idiom more recognizable that way.]


    If your algorithm is most naturally/clearly expressed using a 'goto',
    use the 'goto' keyword. If you bodge together something that is
    LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    typing the word 'goto' because you've heard that 'goto' is bad -- then
    whatever your reason was for avoiding 'goto' will still apply (only
    now you've obfuscated your code for reasons you clearly don't
    understand).

    Half-remembered saws like "Goto considered harmful" will never beat
    clear thinking.
    gwowen, Jul 22, 2011
    #3
  4. On 2011-07-22 08:49, Francois Grieu wrote:
    > I just came into a case where I could use this:
    >
    > do
    > {
    > // local declarations and initializations
    > switch(0)default:
    > {
    > // bunch of if/else; within that:
    > // - "break" performs cleanup;
    > // - "continue" skips cleanup.
    > /*..*/;
    > }
    > /*..*/; // cleanup
    > }
    > while(0);


    I must be missing something. Why can't you just do something like this?

    cleanup = 0;
    if (c1) {
    ...
    cleanup = 1;
    } else if (c2) {

    }...

    }
    if (cleanup) {

    }


    August

    --
    The competent programmer is fully aware of the limited size of his own
    skull. He therefore approaches his task with full humility, and avoids
    clever tricks like the plague. --Edsger Dijkstra
    August Karlstrom, Jul 22, 2011
    #4
  5. In article <>,
    gwowen <> wrote:
    >On Jul 22, 7:49 am, Francois Grieu <> wrote:
    >
    >> [Notes: This is 'only' a way to avoid gotos. It places
    >> restrictions on the use of other do/while/for/switch.
    >> The second brace could be before default, but I find
    >> the dummy switch idiom more recognizable that way.]

    >
    >If your algorithm is most naturally/clearly expressed using a 'goto',
    >use the 'goto' keyword. If you bodge together something that is
    >LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    >typing the word 'goto' because you've heard that 'goto' is bad -- then
    >whatever your reason was for avoiding 'goto' will still apply (only
    >now you've obfuscated your code for reasons you clearly don't
    >understand).
    >
    >Half-remembered saws like "Goto considered harmful" will never beat
    >clear thinking.


    Well, the obvious come-back to this is: What if I work in an environment
    (i.e., company) where use of 'goto' is banned? Then you are suggesting that
    I get a new job?

    --
    "Remember when teachers, public employees, Planned Parenthood, NPR and PBS
    crashed the stock market, wiped out half of our 401Ks, took trillions in
    TARP money, spilled oil in the Gulf of Mexico, gave themselves billions in
    bonuses, and paid no taxes? Yeah, me neither."
    Kenny McCormack, Jul 22, 2011
    #5
  6. On Jul 22, 3:16 pm, (Kenny McCormack)
    wrote:
    > In article <..com>,
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > gwowen  <> wrote:
    > >On Jul 22, 7:49 am, Francois Grieu <> wrote:

    >
    > >> [Notes: This is 'only' a way to avoid gotos. It places
    > >> restrictions on the use of other do/while/for/switch.
    > >> The second brace could be before default, but I find
    > >> the dummy switch idiom more recognizable that way.]

    >
    > >If your algorithm is most naturally/clearly expressed using a 'goto',
    > >use the 'goto' keyword.  If you bodge together something that is
    > >LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    > >typing the word 'goto' because you've heard that 'goto' is bad -- then
    > >whatever your reason was for avoiding 'goto' will still apply (only
    > >now you've obfuscated your code for reasons you clearly don't
    > >understand).

    >
    > >Half-remembered saws like "Goto considered harmful" will never beat
    > >clear thinking.

    >
    > Well, the obvious come-back to this is: What if I work in an environment
    > (i.e., company) where use of 'goto' is banned?  Then you are suggestingthat
    > I get a new job?


    If you can, since obviously the management is _real_ shitty.

    Otherwise heed the advice of Karlstrom, below or hide the goto's in a
    bunch of macro's and sell them as innovative new approach to local
    exception handing. The suits will never know the difference.
    Kleuskes & Moos, Jul 22, 2011
    #6
  7. On 2011/22/07 12:15, August Karlstrom wrote:
    > On 2011-07-22 08:49, Francois Grieu wrote:
    >> I just came into a case where I could use this:
    >>
    >> do
    >> {
    >> // local declarations and initializations
    >> switch(0)default:
    >> {
    >> // bunch of if/else; within that:
    >> // - "break" performs cleanup;
    >> // - "continue" skips cleanup.
    >> /*..*/;
    >> }
    >> /*..*/; // cleanup
    >> }
    >> while(0);

    >
    > I must be missing something. Why can't you just do something like this?
    >
    > cleanup = 0;
    > if (c1) {
    > ...
    > cleanup = 1;
    > } else if (c2) {
    >
    > }...
    >
    > }
    > if (cleanup) {
    >
    > }


    I *CAN*. But I'd rather not. I know that most if not all the compilers I
    use will not notice that the "cleanup" variable can be suppressed, and
    knowing that an extra variable exists and code is here to set and test
    it is causing me brain pain. I'd rather use two gotos (or a single goto
    and a deep nesting of ifs, which often will do the job), and get
    basically the "right" executable.

    If I rationalize: on low-end platforms (PIC..) that I often use, RAM
    size is a few hundred bytes and program space a few kbytes, so every
    byte counts. Even on relatively powerful CPUs (Arm, x86) and when memory
    is not an issue, using one more register may force the shift of
    something into memory rather than in a register, or/and a little extra
    code could abruptly reduce cache efficiency, and in turn slow down
    things considerably. I bet I could construct an articial demo where the
    suggested change increases execution time/power draw quite perceptibly,
    say by 30%.

    Francois Grieu
    Francois Grieu, Jul 22, 2011
    #7
  8. On 2011/07/22 10:46, gwowen wrote :
    > On Jul 22, 7:49 am, Francois Grieu<> wrote:
    >
    >> [Notes: This is 'only' a way to avoid gotos. It places
    >> restrictions on the use of other do/while/for/switch.
    >> The second brace could be before default, but I find
    >> the dummy switch idiom more recognizable that way.]

    >
    > If your algorithm is most naturally/clearly expressed using a 'goto',
    > use the 'goto' keyword. If you bodge together something that is
    > LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    > typing the word 'goto' because you've heard that 'goto' is bad -- then
    > whatever your reason was for avoiding 'goto' will still apply (only
    > now you've obfuscated your code for reasons you clearly don't
    > understand).
    >
    > Half-remembered saws like "Goto considered harmful" will never beat
    > clear thinking.


    I'm not the kind to *blindly* obey a coding recipe. I'm really looking
    at developing idioms that make the code clearer, without leaving the
    simplicity and portability of C for these other languages with
    try/catch. I do prefer:

    do
    {
    /*..*/
    if (errorcondition1)
    break;
    /*..*/
    if (errorcondition2)
    break;
    /*..*/
    if (errorcondition3)
    break;
    /*..*/
    }
    while(0);

    to the alternatives using goto

    {
    /*..*/
    if (errorcondition1)
    goto lerr;
    /*..*/
    if (errorcondition2)

    /*..*/
    if (errorcondition3)
    goto lerr;
    /*..*/
    lerr:;
    }

    [one real drawback of this one is that you can't cut&paste that idiom
    twice in the same function without renaming the label, for C has no way
    to make labels local to a bloc]


    or deep nesting
    {
    /*..*/
    if (!errorcondition1)
    {
    /*..*/
    if (!errorcondition2)
    {
    /*..*/
    if (!errorcondition3)
    {
    /*..*/
    }
    }
    }
    }

    or a variable to remember that there has been an error, which makes the
    source code verbose and the executable perceptibly bigger and (rarely
    perceptibly) less efficient. I just can't stand that idea.


    Sometime, the "dummy do break while" idiom is just not enough, so I'm
    considering "dummy do switch break continue while".


    Francois Grieu
    Francois Grieu, Jul 22, 2011
    #8
  9. On Jul 22, 4:11 pm, Francois Grieu <> wrote:
    > On 2011/22/07 12:15, August Karlstrom wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > On 2011-07-22 08:49, Francois Grieu wrote:
    > >> I just came into a case where I could use this:

    >
    > >> do
    > >> {
    > >> // local declarations and initializations
    > >> switch(0)default:
    > >> {
    > >> // bunch of if/else; within that:
    > >> // - "break" performs cleanup;
    > >> // - "continue" skips cleanup.
    > >> /*..*/;
    > >> }
    > >> /*..*/; // cleanup
    > >> }
    > >> while(0);

    >
    > > I must be missing something. Why can't you just do something like this?

    >
    > > cleanup = 0;
    > > if (c1) {
    > > ...
    > > cleanup = 1;
    > > } else if (c2) {

    >
    > > }...

    >
    > > }
    > > if (cleanup) {

    >
    > > }

    >
    > I *CAN*. But I'd rather not. I know that most if not all the compilers I
    > use will not notice that the "cleanup" variable can be suppressed, and
    > knowing that an extra variable exists and code is here to set and test
    > it is causing me brain pain. I'd rather use two gotos (or a single goto
    > and a deep nesting of ifs, which often will do the job), and get
    > basically the "right" executable.
    >
    > If I rationalize: on low-end platforms (PIC..) that I often use, RAM
    > size is a few hundred bytes and program space a few kbytes, so every
    > byte counts. Even on relatively powerful CPUs (Arm, x86) and when memory
    > is not an issue, using one more register may force the shift of
    > something into memory rather than in a register, or/and a little extra
    > code could abruptly reduce cache efficiency, and in turn slow down
    > things considerably. I bet I could construct an articial demo where the
    > suggested change increases execution time/power draw quite perceptibly,
    > say by 30%.
    >
    >    Francois Grieu


    If such finegrained control is needed, wouldn't you be better off
    using assembly? Most uC targeted compilers i know of mix the two quite
    well.

    From what i read portability isn't a great concern, since you're quite
    specific on the platform, so that can't be the issue.
    Kleuskes & Moos, Jul 22, 2011
    #9
  10. Francois Grieu

    tom st denis Guest

    On Jul 22, 9:16 am, (Kenny McCormack)
    wrote:
    > In article <..com>,
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > gwowen  <> wrote:
    > >On Jul 22, 7:49 am, Francois Grieu <> wrote:

    >
    > >> [Notes: This is 'only' a way to avoid gotos. It places
    > >> restrictions on the use of other do/while/for/switch.
    > >> The second brace could be before default, but I find
    > >> the dummy switch idiom more recognizable that way.]

    >
    > >If your algorithm is most naturally/clearly expressed using a 'goto',
    > >use the 'goto' keyword.  If you bodge together something that is
    > >LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    > >typing the word 'goto' because you've heard that 'goto' is bad -- then
    > >whatever your reason was for avoiding 'goto' will still apply (only
    > >now you've obfuscated your code for reasons you clearly don't
    > >understand).

    >
    > >Half-remembered saws like "Goto considered harmful" will never beat
    > >clear thinking.

    >
    > Well, the obvious come-back to this is: What if I work in an environment
    > (i.e., company) where use of 'goto' is banned?  Then you are suggestingthat
    > I get a new job?


    Potentially yes [all else being weighed in] I'd start looking for a
    new job. At the point where management felt the need to micromanage
    my syntax I'd consider it a hostile work environment.

    As to the general theme, the only real uses for goto's are 1) cleanup
    [exception handling] and 2) getting out of deeply nested loops
    cleanly. Any other use is probably a misuse [there will be other
    cleaner ways to achieve the same thing]. The usual rhetoric about
    "gotos are bad" is just that. In the same way I can write

    (a == 4) && somefunc();

    instead of

    if (a == 4) {
    somefunc();
    }

    While the former is less desirable it doesn't mean that && is a bad
    operator, it means that you can use it in ways that aren't ideal.
    Same with most other keywords and operators.

    Tom
    tom st denis, Jul 22, 2011
    #10
  11. gwowen <> writes:
    > On Jul 22, 7:49 am, Francois Grieu <> wrote:
    >> [Notes: This is 'only' a way to avoid gotos. It places
    >> restrictions on the use of other do/while/for/switch.
    >> The second brace could be before default, but I find
    >> the dummy switch idiom more recognizable that way.]

    >
    > If your algorithm is most naturally/clearly expressed using a 'goto',
    > use the 'goto' keyword. If you bodge together something that is
    > LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    > typing the word 'goto' because you've heard that 'goto' is bad -- then
    > whatever your reason was for avoiding 'goto' will still apply (only
    > now you've obfuscated your code for reasons you clearly don't
    > understand).
    >
    > Half-remembered saws like "Goto considered harmful" will never beat
    > clear thinking.


    But break and continue aren't *just* disguised gotos. They're
    tightly restricted gotos. They branch only to a specific point in
    the code (the end of a certain construct), and unlike gotos they
    can't branch to an earlier point in the code.

    If you really want unmaintainable spaghetti code, backward gotos
    are the way to do it.

    I'm not saying that using a dummy "do { .. } while (0);" just to
    be able to use "break" is a *great* idea (I agree it's a kludge),
    but there are valid arguments in favor of it.

    Another approach for the goto-phobic is to use a call-once function
    so you can return from it.

    Perhaps if C had a few more non-goto control structures (*named*
    break and continue, and perhaps something to terminate a block),
    such kludges wouldn't be needed.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jul 22, 2011
    #11
  12. Francois Grieu

    Stefan Ram Guest

    Kenneth Brody <> writes:
    >Perhaps he should read "'Goto Considered Harmful' Considered Harmful"?


    »Let X be an N x N matrix of integers. Write a program
    that will print the number of the first all-zero row of
    X, if any.«

    untested:

    #include <stdio.h>

    extern int const * const * const X;
    extern int const N;

    static inline int is_all_zero
    ( int const * const row, int const cols )
    { result = 1;
    for( register int col = 0; col != cols; ++col )
    if( m[ col ]){ result = 0; col = cols; } /* I prefer »break«
    or »return« here, but I wanted to show that a version without
    jumps is not that much more complicated. */
    return result; }

    static inline int first_all_zero_row_number_of
    ( int const * const * const m,
    int const rows,
    int const cols )
    { int result = -1;
    for( int row = 0; row != rows; ++row )
    if( is_all_zero( m[ row ]))
    { result = row; row = rows; } /* I prefer »break« or »return« here,
    but I wanted to show that a version without jumps is not that
    much more complicated. */
    return result; }

    int main( void )
    { int const first = first_all_zero_row_number_of( X, N, N );
    if( first >= 0 )printf( "%d\n", first ); }
    Stefan Ram, Jul 22, 2011
    #12
  13. -berlin.de (Stefan Ram) writes:

    > Kenneth Brody <> writes:
    >>Perhaps he should read "'Goto Considered Harmful' Considered Harmful"?

    >
    > »Let X be an N x N matrix of integers. Write a program
    > that will print the number of the first all-zero row of
    > X, if any.«
    >
    > untested:

    <snip>
    > static inline int is_all_zero
    > ( int const * const row, int const cols )
    > { result = 1;
    > for( register int col = 0; col != cols; ++col )
    > if( m[ col ]){ result = 0; col = cols; } /* I prefer »break«
    > or »return« here, but I wanted to show that a version without
    > jumps is not that much more complicated. */
    > return result; }


    You forced the use of a result variable and an assignment to the loop
    control variable by insisting on a for loop. I think this is more
    natural as a while loop:

    int col = 0;
    while (col != cols && m[col]) col++;
    return col == cols;

    > static inline int first_all_zero_row_number_of
    > ( int const * const * const m,
    > int const rows,
    > int const cols )
    > { int result = -1;
    > for( int row = 0; row != rows; ++row )
    > if( is_all_zero( m[ row ]))
    > { result = row; row = rows; } /* I prefer »break« or »return« here,
    > but I wanted to show that a version without jumps is not that
    > much more complicated. */
    > return result; }


    And I'd do the same here.

    > int main( void )
    > { int const first = first_all_zero_row_number_of( X, N, N );
    > if( first >= 0 )printf( "%d\n", first ); }
    >


    --
    Ben.
    Ben Bacarisse, Jul 22, 2011
    #13
  14. Francois Grieu

    Phil Carmody Guest

    Keith Thompson <> writes:
    > gwowen <> writes:
    > > On Jul 22, 7:49 am, Francois Grieu <> wrote:
    > >> [Notes: This is 'only' a way to avoid gotos. It places
    > >> restrictions on the use of other do/while/for/switch.
    > >> The second brace could be before default, but I find
    > >> the dummy switch idiom more recognizable that way.]

    > >
    > > If your algorithm is most naturally/clearly expressed using a 'goto',
    > > use the 'goto' keyword. If you bodge together something that is
    > > LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    > > typing the word 'goto' because you've heard that 'goto' is bad -- then
    > > whatever your reason was for avoiding 'goto' will still apply (only
    > > now you've obfuscated your code for reasons you clearly don't
    > > understand).
    > >
    > > Half-remembered saws like "Goto considered harmful" will never beat
    > > clear thinking.

    >
    > But break and continue aren't *just* disguised gotos. They're
    > tightly restricted gotos. They branch only to a specific point in
    > the code (the end of a certain construct), and unlike gotos they
    > can't branch to an earlier point in the code.


    Continue can. And does. Always.

    Phil
    --
    "At least you know where you are with Microsoft."
    "True. I just wish I'd brought a paddle." -- Matthew Vernon
    Phil Carmody, Jul 22, 2011
    #14
  15. Phil Carmody <> writes:
    > Keith Thompson <> writes:
    >> gwowen <> writes:
    >> > On Jul 22, 7:49 am, Francois Grieu <> wrote:
    >> >> [Notes: This is 'only' a way to avoid gotos. It places
    >> >> restrictions on the use of other do/while/for/switch.
    >> >> The second brace could be before default, but I find
    >> >> the dummy switch idiom more recognizable that way.]
    >> >
    >> > If your algorithm is most naturally/clearly expressed using a 'goto',
    >> > use the 'goto' keyword. If you bodge together something that is
    >> > LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    >> > typing the word 'goto' because you've heard that 'goto' is bad -- then
    >> > whatever your reason was for avoiding 'goto' will still apply (only
    >> > now you've obfuscated your code for reasons you clearly don't
    >> > understand).
    >> >
    >> > Half-remembered saws like "Goto considered harmful" will never beat
    >> > clear thinking.

    >>
    >> But break and continue aren't *just* disguised gotos. They're
    >> tightly restricted gotos. They branch only to a specific point in
    >> the code (the end of a certain construct), and unlike gotos they
    >> can't branch to an earlier point in the code.

    >
    > Continue can. And does. Always.


    C99 6.8.6.2 (emphasis added):

    A continue statement causes a jump to the loop-continuation
    portion of the smallest enclosing iteration statement; that is,
    *to the end* of the loop body.

    The (optional) subsequent branch to the top of the loop is the normal
    operation of the loop itself, not a result of the continue statement.

    This is particularly relevant for a continue in a do-while loop, which
    causes the condition at the bottom to be re-evaluated.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jul 22, 2011
    #15
  16. Francois Grieu

    Phil Carmody Guest

    Keith Thompson <> writes:
    > Phil Carmody <> writes:
    > > Keith Thompson <> writes:
    > >> gwowen <> writes:
    > >> > On Jul 22, 7:49 am, Francois Grieu <> wrote:
    > >> >> [Notes: This is 'only' a way to avoid gotos. It places
    > >> >> restrictions on the use of other do/while/for/switch.
    > >> >> The second brace could be before default, but I find
    > >> >> the dummy switch idiom more recognizable that way.]
    > >> >
    > >> > If your algorithm is most naturally/clearly expressed using a 'goto',
    > >> > use the 'goto' keyword. If you bodge together something that is
    > >> > LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    > >> > typing the word 'goto' because you've heard that 'goto' is bad -- then
    > >> > whatever your reason was for avoiding 'goto' will still apply (only
    > >> > now you've obfuscated your code for reasons you clearly don't
    > >> > understand).
    > >> >
    > >> > Half-remembered saws like "Goto considered harmful" will never beat
    > >> > clear thinking.
    > >>
    > >> But break and continue aren't *just* disguised gotos. They're
    > >> tightly restricted gotos. They branch only to a specific point in
    > >> the code (the end of a certain construct), and unlike gotos they
    > >> can't branch to an earlier point in the code.

    > >
    > > Continue can. And does. Always.


    Yes, this is wrong. But I think only 1/3 wrong.

    > C99 6.8.6.2 (emphasis added):
    >
    > A continue statement causes a jump to the loop-continuation
    > portion of the smallest enclosing iteration statement; that is,
    > *to the end* of the loop body.
    >
    > The (optional) subsequent branch to the top of the loop is the normal
    > operation of the loop itself, not a result of the continue statement.


    Hmmm, I think I disagree. It is for a do {} while, certainly. However,
    in the absense of a definition of "loop-continuation portion", For me
    it's obviously expression_3 for a for loop (which is at the top) and
    the condition for a while loop (which is at the top). Their
    explication introduces more contradiction than explanation. So, to
    their "that is", I'd say "no, that isn't". It would have been better
    if they'd just used the final clause. Were I to be pedantic, I'd take
    issue with your '(optional)' is 2/3 wrong, as it's not optional in
    whiles and fors, only in dos.

    > This is particularly relevant for a continue in a do-while loop, which
    > causes the condition at the bottom to be re-evaluated.


    Yup, you definitely got me there - good call. I dunno why, I was just
    in a 'for' train of thought, and a bit blinkered.

    Phil
    --
    "At least you know where you are with Microsoft."
    "True. I just wish I'd brought a paddle." -- Matthew Vernon
    Phil Carmody, Jul 22, 2011
    #16
  17. On Jul 22, 11:10 am, Kenneth Brody <> wrote:
    > On 7/22/2011 4:46 AM, gwowen wrote:
    >
    >
    >
    > > On Jul 22, 7:49 am, Francois Grieu<>  wrote:

    >
    > >> [Notes: This is 'only' a way to avoid gotos. It places
    > >> restrictions on the use of other do/while/for/switch.
    > >> The second brace could be before default, but I find
    > >> the dummy switch idiom more recognizable that way.]

    >
    > > If your algorithm is most naturally/clearly expressed using a 'goto',
    > > use the 'goto' keyword.  If you bodge together something that is
    > > LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    > > typing the word 'goto' because you've heard that 'goto' is bad -- then
    > > whatever your reason was for avoiding 'goto' will still apply (only
    > > now you've obfuscated your code for reasons you clearly don't
    > > understand).

    >
    > > Half-remembered saws like "Goto considered harmful" will never beat
    > > clear thinking.

    >
    > Perhaps he should read "'Goto Considered Harmful' Considered Harmful"?
    >
    >      http://www.ecn.purdue.edu/ParaMount/papers/rubin87goto.pdf


    Or Knuth's "Structured programming with go to statements", in the
    collection
    <<Literate Programming>>.
    luser- -droog, Jul 23, 2011
    #17
  18. Francois Grieu

    Stefan Ram Guest

    Francois Grieu <> writes:
    >or deep nesting
    > {
    > /*..*/
    > if (!errorcondition1)
    > {
    > /*..*/
    > if (!errorcondition2)
    > {
    > /*..*/
    > if (!errorcondition3)
    > {
    > /*..*/


    It is somewhat sad that often the existence of functions
    is ignored, leading to monolithic code such as seen above.
    (Also in all of the code examples of the preceding post
    that are not quoted here.)

    In the program below, instead, each step is assigned to a
    function, often a function with a meaningful name. The deep
    nesting from above would occur again, if one would nest the
    function blocks at the site where a function is called.

    The following example code reads, sorts, ands prints a list of ints.
    But it is shown here for the way it handles error conditions,
    including proper clean-up code for all resource allocated.
    The functions defined below return error codes as a non-zero value.

    To read the program, it is best to start at the bottom at »main«.
    The actual »main« program with the sequence »read, sort,
    print« is the function »main2«.

    The following code neither uses explicit jump instructions
    nor does it contain deeply nested blocks.

    #include <stdio.h> /* scanf, printf */
    #include <stdlib.h> /* EXIT_SUCCESS */
    #include "simclist-1.4.3/simclist.h" /* list_... */

    int appendvalue( list_t * const list, int *looping )
    { int value;
    if( 1 != scanf( "%d", &value ))return 1;
    if( value >= 0 )
    { if( list_append( list, &value )< 0 )return 2; }
    else *looping = 0;
    return 0; }

    int read( list_t * const list )
    { int looping = 1; while( looping )
    { if( appendvalue( list, &looping ))return 1; }
    return 0; }

    int sort( list_t * const list )
    { if( list_attributes_comparator( list,
    list_comparator_int32_t ))return 1;
    else if( list_sort( list, -1 ))return 2;
    else return 0; }

    int print( list_t * const list )
    { if( list_iterator_start( list )<= 0 )
    return 1;
    { while( list_iterator_hasnext( list ))
    { void * next = list_iterator_next( list );
    if( next )
    { if( printf( "%d\n", *( int * )next )< 0 )return 2; }
    else break; }
    if( !list_iterator_stop( list ))return 3; }
    return 0; }

    int main2( list_t * const list )
    { if( !list_attributes_copy( list, list_meter_int32_t, 1 ))
    { if( read( list ))return 1;
    else if( sort( list ))return 2;
    { printf("Sorted values:\n");
    if( print( list ))return 3; }}
    return 0; }

    int main1( list_t * const list )
    { int result;
    if( list_init( list ))result = 1;
    else
    { if( main2( list ))result = 2;
    list_destroy( list ); }
    return result; }

    int main( void )
    { list_t list;
    return main1( &list )? EXIT_FAILURE : EXIT_SUCCESS; }
    Stefan Ram, Jul 23, 2011
    #18
  19. Francois Grieu

    Stefan Ram Guest

    Keith Thompson <> writes:
    >But break and continue aren't *just* disguised gotos.


    If one would say that »break« and »continue« were
    just disguised »goto« instructions, one also might
    go so far as to say that that »if« and »while«
    or function calls are disguised »goto« instructions,
    and - last, not least - »switch« statements:

    while( pc != 99 )
    { switch( pc++ )
    { case 0: ...; break;
    case 1: ...; break;
    case 2: ...; break; ... }}

    Above, a »goto« becomes »pc = ...;«.
    Stefan Ram, Jul 23, 2011
    #19
  20. luser- -droog <> writes:

    > On Jul 22, 11:10 am, Kenneth Brody <> wrote:
    >> On 7/22/2011 4:46 AM, gwowen wrote:
    >>
    >> > On Jul 22, 7:49 am, Francois Grieu<>  wrote:

    >>
    >> >> [Notes: This is 'only' a way to avoid gotos. It places
    >> >> restrictions on the use of other do/while/for/switch.
    >> >> The second brace could be before default, but I find
    >> >> the dummy switch idiom more recognizable that way.]

    >>
    >> > If your algorithm is most naturally/clearly expressed using a 'goto',
    >> > use the 'goto' keyword.  If you bodge together something that is
    >> > LOGICALLY a 'goto' using keywords-that-aren't-goto -- simply to avoid
    >> > typing the word 'goto' because you've heard that 'goto' is bad -- then
    >> > whatever your reason was for avoiding 'goto' will still apply (only
    >> > now you've obfuscated your code for reasons you clearly don't
    >> > understand).

    >>
    >> > Half-remembered saws like "Goto considered harmful" will never beat
    >> > clear thinking.


    Agreed. Also, when you meet anyone who comes out with either "goto
    considered harmful" or who dismissed the idea out of hand, ask them what
    Dijkstra's argument actually *is* (i.e. ask them what it is they are
    defending or rejecting). You will be surprised by how many people have
    a strong view of this paper without knowing what's in it.

    >> Perhaps he should read "'Goto Considered Harmful' Considered Harmful"?
    >>
    >>      http://www.ecn.purdue.edu/ParaMount/papers/rubin87goto.pdf


    Only if you want to see how not to counter the argument.

    > Or Knuth's "Structured programming with go to statements", in the
    > collection
    > <<Literate Programming>>.


    Which states:

    "This study focuses largely on two issues: (a) improved syntax for
    iterations and error exits, making it possible to write a larger class
    of programs clearly and efficiently without goto statements; (b)
    a methodology of program design, beginning with readable and correct,
    but possibly inefficient programs that are systematically transformed
    if necessary into efficient and correct, but possibly less readable
    code."

    In other words it is not written as any sort of refutation of Dijkstra's
    paper but aims to take the debate forward by finding ways to mitigate
    the dangers posed by "the unbridled use of the goto" (Dijkstra's
    phrase).

    Later on Knuth writes:

    "some readers [...] are convinced that abolition of go to statements
    is merely a fad. and they may see this title and think, 'Aha! Knuth is
    rehabilitating the go to statement, and we can go back to our old ways
    of programming again.'"

    This is crucial. You can't understand Dijkstra's paper unless you put
    it in context. I remember the "old ways" of spaghetti code but most
    recent programmers do not because, in essence, Dijkstra won the
    argument; almost no one advocates the unbridled use of the goto anymore.

    --
    Ben.
    Ben Bacarisse, Jul 23, 2011
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    36
    Views:
    1,479
    Chris Uppal
    Jun 6, 2005
  2. Jianli Shen
    Replies:
    3
    Views:
    2,054
  3. Replies:
    16
    Views:
    3,587
    steve
    Jul 11, 2006
  4. viza

    break or continue out of nested loops

    viza, Jul 16, 2003, in forum: C Programming
    Replies:
    5
    Views:
    1,017
    sunil
    Jul 17, 2003
  5. Glen Wheeler

    continue and break frustration

    Glen Wheeler, Dec 14, 2003, in forum: Python
    Replies:
    5
    Views:
    404
    Rene Pijlman
    Dec 16, 2003
Loading...

Share This Page