【问题标题】:What is the advantage of a do-while(false)?do-while(false) 的优点是什么?
【发布时间】:2010-11-29 12:33:55
【问题描述】:

在查看由其他员工处理的一些代码时,我看到很多代码是这样写的:

do{
    ...
}while(false);

这有什么好处(如果有的话)?

下面是代码中发生的更多骨架:

try{
    do{
        // Set some variables

        for(...) {
            if(...) break;
            // Do some more stuff
            if(...) break;
            // Do some more stuff
        }
    }while(false);
}catch(Exception e) { 
    // Exception handling 
}

更新:

C++ 版本:
Are do-while-false loops common?

【问题讨论】:

  • 主要优点是它告诉你其他员工需要交谈!
  • 为什么是近距离投票?这是完全一个真正的问题!
  • 对我来说看起来很疯狂......
  • 另一位员工?就像你旁边工作的人一样?并可能交谈?并可能得到答案?
  • @kdgregory:对不起,我应该说是前雇员。我联系不上他。但他所有的代码都包裹在这个里面。

标签: java loops while-loop


【解决方案1】:

也许这样做是为了能够随时跳出“循环”,例如:

do
{
    ...
    if (somethingIsWrong) break;
    //more code
    ...
}
while(false);

但正如其他人所说,我不会这样做。

【讨论】:

  • 是的,让我们破解我们的语言没有goto的事实!
  • 哇 - 这是一个 Java 风格的 goto! (但它乞求成为一个有条件返回的函数......)
  • @mmyers:它或多或少与(ab-)使用流控制异常
  • 我很确定,让这个更复杂的唯一方法是在两者之间使用 try {} finally {} 块。这段代码让我很难过。
  • @Tom,因为当你看到 return 时,你知道你是什么方法。但是如果你看到一个“中断”,你通常会想“哦,那是在循环之外——等等,循环??”,我认为这只是令人困惑。
【解决方案2】:

在 Java 中,没有理由这样做。

在 C 中,这是定义宏时的常用习语:

考虑:

#define macro1 doStuff(); doOtherStuff()
#define macro2 do{ doStuff(); doOtherStuff(); } while( false )

if( something ) macro1; // only the first statement in macro1 is executed conditionally
if( something ) macro2; // does what it looks like it does

...但是 C 中的宏是邪恶的,应尽可能避免使用。

你的同事是否有 C 背景?

【讨论】:

    【解决方案3】:

    没有优势。不要这样做。

    【讨论】:

    • 它的优点是激怒了mmyers。这还不够吗?
    • 我没有生气。再说一次,我不必维护这家伙的代码。
    • 应该被激怒了。你没看到他的while循环吗! ;)
    【解决方案4】:

    它可以用来转到一个块的末尾,可以用来避免一堆嵌套的 if/then 块。

    do {
        if (done()) continue;
        // do a bunch of stuff
        if (done()) continue;
        // do a bunch more stuff
        if (done()) continue;
        // do even more stuff
    } while (false);
    

    【讨论】:

      【解决方案5】:

      这在 C 中用于定义宏内部的块。例如,请参阅this

      例如,以下无效:

      #define f(x) { g(x); h(x); }
      
      if (x >= 0) f(x); else f(-x);
      

      但是有了这个定义,它就会起作用:

      #define f(x) do { g(x); h(x) } while(false)
      

      【讨论】:

      • Java 没有宏,如果在右大括号后有一个分号,在 Java 中是合法的,因此不需要。
      • 有分号是合法的,除非你想把'else'放在那里。如果 () {}; else {} - 是非法的
      • 您可能想对此进行扩展。
      • 这似乎是最合乎逻辑的解释,并支持@moonshadow。
      【解决方案6】:

      它没用,但是编码器可以使用多个中断命令来进行一些奇怪的异常处理。

      do{
      if(<something>){...}else{break}
      if(<something else>){...}else{break}
      ...
      }while(false)
      

      承认它很愚蠢,但我确实曾经在旧的 c 程序中找到过类似的东西

      【讨论】:

      • 今天刚碰到这个。在 C++ 方法的主体中发现了这个构造并想知道,WTF?谷歌把我带到了这里,这似乎是最有可能的答案。原来的编码器有多个 if (errorCond) { /* do something */ break; do..while 块中的 } 语句。我能看到的唯一优势是从方法中提供一个返回点(在方法的末尾,就像我正在查看的代码中的情况一样)而不是几个。我不会那样编码,但我可以明白为什么这样做。
      【解决方案7】:

      你的直觉是对的。这是完全没用的事情。

      可能编码它的人最初将false以外的东西作为条件,只是将其更改为false而不是删除整个块以免丢失这个“历史”的代码。然而,这只是抓住稻草。坦率地说,这只是 tautology 的一个简单示例,它在代码中没有位置。

      【讨论】:

      • 哇,突然投反对票是怎么回事?在您投反对票时发表评论是礼貌的,原因尚未解释!
      • +1 让您的帖子再次上升。但是,我可以想象有些人对您与“逻辑重言式”的类比感到困惑,并认为您所说的“虚假”是重言式。你能详细说明一下这个类比吗?
      • @litb:干杯。是的,我可能在那里使用了错误的重言式。从这个词的常识来看,这当然是一个重言式:您编写一次代码,然后再次(不必要地)添加do { ... } while (false) 的事实表明它应该添加一次。
      【解决方案8】:

      在 C/C++ 以外的几乎所有语言中,这都没有提供任何战术优势。

      在 C/C++ 中,有一种宏的情况,其中 do/while(false) 可以更轻松地将宏安全地扩展为多个语句。当宏看起来像一个普通的函数调用时,这是有利的。

      【讨论】:

        【解决方案9】:

        看看这个question

        OP 询问了这个确切的结构并解释了使用它的一些原因。共识似乎是这样做是件坏事。

        【讨论】:

          【解决方案10】:

          当其他条件代替false时,作为未来的占位符。

          【讨论】:

            【解决方案11】:

            它可以用来跳过某些代码的执行(比如goto 或其他东西),但是当我再次查看它时,似乎有一个for 循环(if(...) break; 语句所在的位置)在do-while。否则,我会说它是 goto 的 Java 版本...

            【讨论】:

              【解决方案12】:

              我多年来一直使用这个约定!当您拥有处理和/或条件检查的“管道”时,它最有用。它只是避免了多层嵌套 if() 语句,从而使代码(更)易于阅读。是的,有诸如 try/catch 之类的替代方法,我只在某些瘦/低级别的情况下使用这种风格。

              我用类似...的评论开始“循环”(实际上从不循环)

              // Error loop (never loops)
              

              错误循环是...

              set errorCode = fail;
              do {
                if (this)
                  break;
              
                if (that)
                  break;
              
                // Success
                set errorCode = ok;
              
                // Alternative Success
                errorCode = doWhatever();
              } while (false);
              

              如果您有一堆嵌套的 if() 语句并且您的缩进深度超过 3 层,请考虑这种样式。

              我在 Perl、C/C++、Java 和 Delphi/Pascal 中使用过这个约定。

              【讨论】:

                【解决方案13】:

                我猜那个作者不相信他的代码,所以他曾经运行它几次,看看它是否让它更有效,这就是它的考古遗迹。

                【讨论】:

                  【解决方案14】:

                  我能想到的唯一原因是创建一个块以使在{...} 中声明的变量的范围更窄,但是有更好的方法来做到这一点(比如创建函数,或者只是创建块 - 给皮特的小贴士柯克姆)。

                  【讨论】:

                  • 是的,虽然我个人觉得代码中的随机块很碍眼。
                  • 肯定do ... while (false) 不只是眼痛,还是脑痛?
                  • @dtsazza - 同意。我并不是说这是一种好的编码方式,只是说这可能是开发人员最初正在做的事情,尽管我承认我发现 Martin 的建议更有说服力。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-05-30
                  • 1970-01-01
                  • 2021-08-19
                  • 2016-07-14
                  • 2021-12-20
                  • 2013-04-10
                  相关资源
                  最近更新 更多