【问题标题】:How do you write a no-op statement?你如何写一个无操作声明?
【发布时间】:2011-11-24 02:08:42
【问题描述】:

在 Delphi 中编写 no-op statement 的最佳方法是什么?

获取此代码:

if a=b then
  SomeOldStatement
else
  AnotherStatement;

并说你暂时想退出SomeOldStatement

你会选择这个解决方案吗:

if a=b then
  //SomeOldStatement
else
  AnotherStatement;

就我个人而言,我不喜欢空的 then 部分,并希望在其中有 一些东西可编译...

if a=b then
  NoOp
  //SomeOldStatement
else
  AnotherStatement;

【问题讨论】:

  • 你试过asm nop end;吗?
  • @RRUZ:没试过,但我想到了这个替代方案。我想它工作正常,但它与内联 asm 非法的 64 位不兼容。
  • procedure Noop; asm nop end; 可以。我想这是最好的解决方案。您应该添加您的建议作为答案:-)
  • 我更喜欢“//DoNothing”而不是“//SomeOldStatement”。在这种情况下,您也可以使用 Assert(a=b)。
  • @JørnE.Angeltveit,但是如果你将nop 指令放在一个名为Noop 的过程中,你将添加一个JMP 和RET 指令,这与直接添加的实际效果不同nop 指令。在这种情况下不是更好只有一个空程序procedure Noop; begin end;?

标签: delphi coding-style noop


【解决方案1】:

不知道你为什么需要任何东西(例如,我对“then else”很满意)。

但如果你想要在那里编译的东西,我会这样做:

if a=b then
  begin end
  //SomeOldStatement
else
  AnotherStatement;

一个空的开始块是我所知道的 Delphi 中最好的 noop。它不会产生汇编代码,因此不会产生开销。

【讨论】:

  • 我猜一个空的begin-end 块是最好的解决方案。 (这实际上是我在等待一些更好的选择时实施的)。 ; 需要离开,顺便说一句...
  • 我真的很喜欢 // DO NOTHING 作为空开始/结束块内的评论。它使代码通读干净。
【解决方案2】:
if a=b then 
  SomeOldStatement 
else 
  AnotherStatement; 

应该写成

if a=b then
begin
  SomeOldStatement;
end 
else
begin
  AnotherStatement; 
end;

现在,您可以注释掉 SomeOldStatement;与您所追求的效果完全相同,调试器更准确地遵循代码流,并且您可以避免代码中出现奇怪的副作用,例如

if a=b then
  if b=c then
    statement1
  else
    if c=d then
      statement2;
  else
   statement2
else 
  statement3;

搞砸你的缩进,弄错分号,记录一行以供测试和废话,事情很快就会变得丑陋。

说真的,试着弄清楚我刚刚写的代码在没有编译器通过的情况下是否有效。

现在,猜猜这会发生什么:

if a=b then
if b=c then
statement1
else
if c=d then
statement2;
// else
statement2
else 
statement3;

还有:

if a=b then
  statement1;
  statement2;

经常会做一些奇怪的事情,当你做的时候甚至会做一些奇怪的事情

if a=b then
//  statement1;
statement2;

严重 - 只需养成在所有逻辑中始终以开头结尾的习惯 - 它使您的代码更易于遵循、避免副作用、避免心理解析错误、代码解析错误和注释掉副作用。

另外,一个空的开始/结束与你的无操作相同。

【讨论】:

  • +1 单/复合语句区分是可怕的,这是解决方法
【解决方案3】:

在Delphi 2005及后续版本中,可以定义一个NoOp空过程,并标记为inline

除非您在编译器选项中定义{$INLINE OFF}或将代码内联控制设置为关闭,否则不会生成任何代码。

procedure NoOp; inline;
begin
  // do nothing
end;

生成的代码非常干净:

if a=b then
  NoOp //SomeOldStatement
else
  AnotherStatement;

【讨论】:

    【解决方案4】:

    这是最好的选择。我将它广泛用于调试,因为我可以在此处设置断点,不依赖于其他单元,不会以任何方式干扰您的程序,并且比条件断点快得多。

    if a=b then
      asm nop end
    else
      AnotherStatement;
    

    【讨论】:

      【解决方案5】:

      你可以使用a:=a 之类的东西,但老实说,我发现它甚至比非陈述更 - 你应该编写代码,这样你之后的人就会明白你的意思意图,并且命令 a:=a 并没有真正遵循该准则。

      因为这只是一个临时的东西,我会认为你没有可执行代码。如果如您所说,Delphi 仍然可以正常编译,那么您没有问题。

      如果你想要一些代码用于断点,并且没有更好的方法,我会考虑暂时做a:=a的事情。

      如果要进行更永久的更改,则可以考虑反转条件,以使您根本没有空块:

      if not (a = b) then
          AnotherStatement;
      

      或者,更好的是:

      if a <> b then
          AnotherStatement;
      

      【讨论】:

      • 我同意在这是最终代码的情况下,应该与 De Morgan 进行一些并行编程。我尽量避免空语句的原因在这里描述:delphi.about.com/od/beginners/a/delphi-if-then-else-traps.htm
      • 优化编译器可能会将 a:=a 优化掉,所以你不会得到断点。
      • 为空语句设置 "a := a" 代价高昂,如果 "a" 类型是托管类型(可以清除该值),您可能会得到错误代码。
      【解决方案6】:

      作业怎么样,a := a?那是无操作的。

      (我不了解 Delphi,所以赋值的语法可能是错误的,但希望您能理解并在需要时更正语法)

      【讨论】:

      • a=a 是一个比较,而不是一个赋值。 a:=a 就是你要找的 :-)
      【解决方案7】:

      如果没有begin end 块的语句是一个等待发生的错误,在这种情况下添加begin end 块将允许您注释掉您的行而无需更改任何更多代码。

      【讨论】:

        猜你喜欢
        • 2015-10-23
        • 2010-12-28
        • 1970-01-01
        • 2022-06-13
        • 1970-01-01
        • 2020-07-31
        • 2010-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多