Hey, look, I can write one line of code in three lines!



  • Just perusing some code and found several occurances of this.  Guess the guy just liked loops (or has some obsessive compulsive disorder)

    do{
        ...
    }while(false);



  • Why anyone would do that is beyond me... the looping construct used here is completely useless



  • do {} while(false) is used commonly in C and C++ preprocessor macros to safely macro in multiple statements so that expanded macros will still perform consistently regardless of coding style.

    For example, a macro

    #define   mrMacro(a,b,c)   func1(a,b); b=c; func2(b,c)

    used in a situation like:

    if(true) mrMacro(varA, varB, varC);

    will expand into

    if(true) func(varA, varB); varB = varC; func2(varB, varC);

    which executes the last 2 statements regardless of the conditional test.

    using a do { } while(false) to encapsulate the entire macro means that they will always be included

    if(true) do { func(varA, varB); varB = varC; func2(varB, varC); } while(false);

    and the compiler will detect the constant result of the while clause and remove the entire loop as a basic exercise in simple optimization.

     

    Another reason to use do { } while(false); is to offer a common point for break; statements, allowing your code to skip later sections based on whatever.

    do { if(a) break; doStuff; if(b) break; doMoreStuff(); if(c) break; doEvenMoreStuff(); } while(false);

    much like a reverse switch statement with no breaks, allowing control flow to trickle down through cases that follow.



  • @Iluvitar said:

    using a do { } while(false) to encapsulate the entire macro means that they will always be included

    if(true) do { func(varA, varB); varB = varC; func2(varB, varC); } while(false);



    Er.

    How about not being a character count neurotic and just doing:

    If (true) {
       mrMacro(varA, varB, varC);
    }
    


  • @dhromed said:


    How about not being a character count neurotic and just doing:
    If (true) {
    mrMacro(varA, varB, varC);
    }

    That demands the developer who writes it either makes it a habit to use {} excessively, or is aware that it is indeed a macro.

    (Is my "excessive use" your "non-neurotic"? Some keyboard setups have them a bit hard to reach, btw. Try right-alt (leftalt won't work) and 7, for instance. See if it breaks your stride too.)

     

    That said, there can still be cases where the break and continue keywords are used in the block - and then it becomes a wholly different ballgame. By then it goes all the way from wtf to clever trick. (Much can be said about clever tricks, but that's not a discussion for here, I think.) As someone said, a reverse switch/case.

    Though so far, I have only encountered it as

    while (1) {

    //...

    break;

    }

    Which is a slight wtf.



  • @dhromed said:

    @Iluvitar said:

    using a do { } while(false) to encapsulate the entire macro means that they will always be included

    if(true) do { func(varA, varB); varB = varC; func2(varB, varC); } while(false);



    Er.

    How about not being a character count neurotic and just doing:

    If (true) {
       mrMacro(varA, varB, varC);
    }
    

    Couldn't we just define the macro as mrMacro(a,b,c) { func1(a,b); b=c; func2(b,c)}?



  • @masklinn said:

    @dhromed said:
    @Iluvitar said:

    using a do { } while(false) to encapsulate the entire macro means that they will always be included

    if(true) do { func(varA, varB); varB = varC; func2(varB, varC); } while(false);



    Er.

    How about not being a character count neurotic and just doing:

    If (true) {
       mrMacro(varA, varB, varC);
    }
    

    Couldn't we just define the macro as mrMacro(a,b,c) { func1(a,b); b=c; func2(b,c)}?

    IIRC, that breaks if you do:

    if(foo) mrMacro(bar,baz,foogle); else do_something_else();

    This'd be perfectly correct if mrMacro was a function, but as it's a macro it expands to:

    if(foo) { func1(bar,baz); b=c; func2(baz,foogle); }; else do_something_else

    which unfortunately isn't valid C due to the semicolon, whereas with do { ... } while(0) everything works as expected.



  • @Iluvitar said:

    A macro

    #define   mrMacro(a,b,c)   func1(a,b); b=c; func2(b,c)

    used in a situation like:

    if(true) mrMacro(varA, varB, varC);

    will expand into

    if(true) func(varA, varB); varB = varC; func2(varB, varC);

    which executes the last 2 statements regardless of the conditional test.



    I once saw a system where the } of some [code]else[/code] was  inside an included file. I kept wondering why the accolades didn't match up.

    This macro reminds me of that. Defining a macro like that is the problem, and the do..while(false) is a patch, not the solution.

    Some keyboard setups have them a bit hard to reach, btw.


    Valid point, I guess. Though maybe you could consider getting a different keyboard, seeing as how {} are rather ubiquitous in most languages. :)

Log in to reply