Help understanding this use of while

Discussion in 'C Programming' started by Chris Saunders, Mar 20, 2009.

  1. I saw this code and don't understand this use of while. It seems to me
    that the while loop will just occur once but then why use a while loop
    at all? Here's the code:

    #define SWAP_PTRS(x_dummy_p, y_dummy_p) \
    do { \
    fmpz_t swap_temp_p = x_dummy_p; \
    x_dummy_p = y_dummy_p; \
    y_dummy_p = swap_temp_p; \
    } while(0);

    Regards
    Chris Saunders
     
    Chris Saunders, Mar 20, 2009
    #1
    1. Advertising

  2. On Thu, 19 Mar 2009 22:15:12 -0400, Chris Saunders
    <> wrote:

    >I saw this code and don't understand this use of while. It seems to me
    >that the while loop will just occur once but then why use a while loop
    >at all? Here's the code:
    >
    >#define SWAP_PTRS(x_dummy_p, y_dummy_p) \
    >do { \
    > fmpz_t swap_temp_p = x_dummy_p; \
    > x_dummy_p = y_dummy_p; \
    > y_dummy_p = swap_temp_p; \
    >} while(0);


    It allows you to generate constructs such as
    if (x) SWAP_PTRS(y,z)

    Think about what would happen if the macro did not contain the "do"
    and "while" lines.

    --
    Remove del for email
     
    Barry Schwarz, Mar 20, 2009
    #2
    1. Advertising

  3. Chris Saunders <> writes:

    > I saw this code and don't understand this use of while. It seems to
    > me that the while loop will just occur once but then why use a while
    > loop at all? Here's the code:
    >
    > #define SWAP_PTRS(x_dummy_p, y_dummy_p) \
    > do { \
    > fmpz_t swap_temp_p = x_dummy_p; \
    > x_dummy_p = y_dummy_p; \
    > y_dummy_p = swap_temp_p; \
    > } while(0);


    It is (as pete has pointed out) a mistake. The usual case is without
    the final ;. The logic goes like this:

    You want a macro that has a declaration. You need a block for that.
    If you write this:

    #define SWAP(a,b) { T t=a; a=b; b=t; } /* ()s omitted for clarity */

    then things go wrong if you write:

    if (C)
    SWAP(x, y);
    else something_else();

    Expand SWAP and look closely and you will see am empty statement
    before the else. This is not valid syntax. So, what construct in C
    has a block but can have a trailing ; and still remain a single
    statement? Ah:

    #define SWAP(a,b) do { T t=a; a=b; b=t; } while (0)

    Now SWAP(x,y); is a correct, single statement.

    If you don't omit the trailing ; from the macro, you might as well
    just use a plain block and avoid the odd looking do ... while (0).

    --
    Ben.
     
    Ben Bacarisse, Mar 20, 2009
    #3
  4. Chris Saunders <> writes:
    > I saw this code and don't understand this use of while. It seems to
    > me that the while loop will just occur once but then why use a while
    > loop at all? Here's the code:
    >
    > #define SWAP_PTRS(x_dummy_p, y_dummy_p) \
    > do { \
    > fmpz_t swap_temp_p = x_dummy_p; \
    > x_dummy_p = y_dummy_p; \
    > y_dummy_p = swap_temp_p; \
    > } while(0);


    This is question 10.4 of the comp.lang.c FAQ, <http://www.c-faq.com/>.

    --
    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, Mar 20, 2009
    #4
  5. Barry Schwarz <> writes:

    > On Thu, 19 Mar 2009 22:15:12 -0400, Chris Saunders
    > <> wrote:
    >
    >>I saw this code and don't understand this use of while. It seems to me
    >>that the while loop will just occur once but then why use a while loop
    >>at all? Here's the code:
    >>
    >>#define SWAP_PTRS(x_dummy_p, y_dummy_p) \
    >>do { \
    >> fmpz_t swap_temp_p = x_dummy_p; \
    >> x_dummy_p = y_dummy_p; \
    >> y_dummy_p = swap_temp_p; \
    >>} while(0);

    >
    > It allows you to generate constructs such as
    > if (x) SWAP_PTRS(y,z)
    >
    > Think about what would happen if the macro did not contain the "do"
    > and "while" lines.


    True, but if the author of the macro intended the user of it do the
    above (i.e. to watch his of her semicolons like a hawk) then what is
    the point of the 'do' and the 'while(0);' -- i.e. why not just use a
    block? It would be simpler and raise fewer questions. The whole
    point of the do ... while (0) trick is to introduce a block that is
    just one semicolon short of a full statement.

    --
    Ben.
     
    Ben Bacarisse, Mar 20, 2009
    #5
  6. Chris Saunders

    CBFalconer Guest

    Chris Saunders wrote:
    >
    > I saw this code and don't understand this use of while. It seems
    > to me that the while loop will just occur once but then why use a
    > while loop at all? Here's the code:
    >
    > #define SWAP_PTRS(x_dummy_p, y_dummy_p) \
    > do { \
    > fmpz_t swap_temp_p = x_dummy_p; \
    > x_dummy_p = y_dummy_p; \
    > y_dummy_p = swap_temp_p; \
    > } while(0);


    Leave off the final ';'. Then the macro acts normally in all code.
    e.g.:

    if (something) SWAP_PTRS(x, y);
    else {
    /* other code */
    }

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Mar 20, 2009
    #6
  7. Chris Saunders

    Lew Pitcher Guest

    On March 22, 2009 16:13, in comp.lang.c, Malcolm McLean
    () wrote:

    >
    > "Chris Saunders" <> wrote in message
    >>I saw this code and don't understand this use of while. It seems to me
    >>that the while loop will just occur once but then why use a while loop at
    >>all? Here's the code:
    >>
    >> #define SWAP_PTRS(x_dummy_p, y_dummy_p) \
    >> do { \
    >> fmpz_t swap_temp_p = x_dummy_p; \
    >> x_dummy_p = y_dummy_p; \
    >> y_dummy_p = swap_temp_p; \
    >> } while(0);
    >>

    > C doesn't allow bare blocks.


    Hmmmm.... what do you mean by that? Why doesn't a C "compound statement"
    qualify as a "bare block"?


    > So if you have a multi-line macro, and a
    > controlling statement
    >
    > eg
    >
    > #define MYMACRO() printf("Hello");printf("World");
    > if(x == y)
    > MYMACRO();
    >
    > "World" will be printed if x != y, which probably isn't what you want.


    OTOH, if the macro were
    #define MYMACRO() { printf("Hello"); printf("World"); }
    then
    if (x==y)
    MYMACRO();
    would work as expected.

    > The do ... while(0) is a hack to get round that oversight. It works very
    > well.


    I think that you really wanted to illustrate
    if (x == y)
    MYMACRO();
    else
    do_something_else();

    If MYMACRO() expanded to a full statement (either a semi-colon terminated
    single statement, or a brace bracketed compound statement), the trailing
    semicolon from the unexpanded invocation (the semicolon at the end
    of "MYMACRO();") would be taken as a new (empty) statement at the same
    level as the "if" statement.

    This, in turn, would "unpair" the following "else" statement from the "if"
    statement, causing a syntax error upon compilation.

    The "do { } while(0)" macro expansion takes advantage of the syntax of the
    do/while verb, along with the behaviour of the while(0) condition, to
    permit a single pass through the "do {} while()" logic (like the compound
    statement would permit), while permitting (requiring) the macro invocation
    to be treated as a single statement, terminated with a semicolon. Thus, the
    semicolon that follows the MYMACRO() invocation is paired with the while()
    clause of the expanded macro, and the "else" is left to be properly paired
    with the preceding "if".

    The drawback to using a "do {} while(0)" macro is that the invocation /must/
    be terminated with a semicolon. This means that it is /not/ proper to use
    this sort of macro as anything other than the rightmost rvalue of a
    statement. In other words, you can't use it as
    a = MYMACRO() + 6;
    or even
    a = MYMACRO(), 10;

    --
    Lew Pitcher

    Master Codewright & JOAT-in-training | Registered Linux User #112576
    http://pitcher.digitalfreehold.ca/ | GPG public key available by request
    ---------- Slackware - Because I know what I'm doing. ------
     
    Lew Pitcher, Mar 22, 2009
    #7
  8. Chris Saunders

    Phil Carmody Guest

    "Malcolm McLean" <> writes:
    > "Chris Saunders" <> wrote in message
    >> I saw this code and don't understand this use of while. It seems to
    >> me that the while loop will just occur once but then why use a while
    >> loop at all? Here's the code:
    >>
    >> #define SWAP_PTRS(x_dummy_p, y_dummy_p) \
    >> do { \
    >> fmpz_t swap_temp_p = x_dummy_p; \
    >> x_dummy_p = y_dummy_p; \
    >> y_dummy_p = swap_temp_p; \
    >> } while(0);

    >
    > C doesn't allow bare blocks.


    What's that supposed to mean?

    #include <stdio.h>
    int main()
    {
    {
    int ImInABareBlock=1;
    printf("He's in a bare block - %i", ImInABareBlock);
    }
    }

    Quite how you'd like that bare block to be adorned in order
    to be not allowed, I don't know, but I suspect it'd not be
    sensibly called a bare block afterwards.

    Phil
    --
    Marijuana is indeed a dangerous drug.
    It causes governments to wage war against their own people.
    -- Dave Seaman (sci.math, 19 Mar 2009)
     
    Phil Carmody, Mar 22, 2009
    #8
    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. Brad
    Replies:
    3
    Views:
    351
    Tim Roberts
    Feb 19, 2008
  2. VJ
    Replies:
    2
    Views:
    92
    Thomas 'PointedEars' Lahn
    Oct 4, 2007
  3. Terry Reedy

    Understanding while...else...

    Terry Reedy, Jan 22, 2013, in forum: Python
    Replies:
    0
    Views:
    112
    Terry Reedy
    Jan 22, 2013
  4. Ethan Furman

    Re: Understanding while...else...

    Ethan Furman, Jan 22, 2013, in forum: Python
    Replies:
    0
    Views:
    119
    Ethan Furman
    Jan 22, 2013
  5. Terry Reedy

    Re: Understanding while...else...

    Terry Reedy, Jan 22, 2013, in forum: Python
    Replies:
    0
    Views:
    134
    Terry Reedy
    Jan 22, 2013
Loading...

Share This Page