繁体   English   中英

如何重构此C ++来删除标签/标签?

[英]How can I refactor this C++ to remove the labels/gotos?

我的问题并不是真正的问题,但是我想使这段代码看起来比现在的更优雅。 它具有意大利面条代码。

这是我得到的一个小例子。

 int func(...) {
  if ( ... )
  {
    v6 = ESI_1C;
    EBP = 1;
    v5 = 0;
    v21 = 0;
    v19 = 0;
    v25 = ESI_1C;
    if ( packetSize > 1 )
    {
      v26 = (unsigned __int8)initialCryptAnswer;
      v10 = v8 - v6;
      v11 = v6 + 4;
      for ( i = v8 - v6; ; v10 = i )
      {
        v12 = *(DWORD *)(v10 + v11);
        v21 += v12;
        cryptAnswer = (unsigned __int8)cryptTable[(2 * (unsigned __int8)v26)+1];
        v13 = EBP & 3;
        if ( !(EBP & 3) )
          break;
        if ( v13 == 1 ) {
          v16 = cryptAnswer >> 1;
          *(DWORD *)v11 = v12 - v16;
        } else if ( v13 == 2 ) {
          *(DWORD *)v11 = v12 + 2 * cryptAnswer;
        } else if ( v13 == 3 ) {
          v16 = cryptAnswer >> 2;
          *(DWORD *)v11 = v12 - v16;
        }
LABEL_19:
        v17 = *(DWORD *)v11 + v19;
        ++EBP;
        v11 += 4;
        v19 = v17;
        ++v26;
        if ( EBP >= packetSize )
        {
          ESI = v24;
          v5 = v17;
          v6 = v25;
          goto LABEL_22; //kinda like break it's much more because it's instead of a for loop too.
        }
      }
      *(DWORD *)v11 = v12 + 4 * cryptAnswer;
      goto LABEL_19; //this is a looper
    }
LABEL_22:
    result = 1;
  } else {
    result = 0;
  }
  return result;
}

我该怎么做才能摆脱标签的困扰而又不弄乱代码流,因为这是加密功能中非常重要的一部分?

第二个答案,因为问题变化很大。

删除所有多余的内容后,原始代码如下所示:

for (... ; ; ...)
{
  ...
  if (...)
  {
    break;
  }
  ABC
LABEL_19:
  DEF
}
XYZ;
goto LABEL_19;

这与以下内容完全相同:

for (... ; ; ...)
{
  ...
  if (...)
  {
    XYZ;
  }
  else
  {
    ABC
  }

  DEF
}

完成此重写后,可以使用简单的break替换goto LABEL_22

编辑:或更明确地说:

for (... ; ; ...)
{
  ...
  if (! (ESP & 3) )
  {
    // This line used to be located after the loop.
    *(DWORD *)v11 = v12 + 4*cryptAnswer;  // 111
  }
  else
  {
    if (v13 == 1)
    {
      ...
    }
    else if (v13 == 2)
    {
      ...
    }
    else if (v13 == 3)
    {
      ...
    }
  }

  // This is where LABEL_19 used to be.

  v17 = ...      // 222
}

像这样重写代码时的经验法则是,代码应按照与以前相同的顺序执行相同的操作。 您根本不能盲目地移动代码,而要做到这一点,您必须了解代码流程。 在这种情况下,当采用第一个if时,将首先执行我用// 111标记的行,然后执行// 222的行。

永远不会执行goto LABEL_1 ,因为没有办法退出for循环。

删除后,您可以将break替换为goto LABEL_2 ,甚至可以简单地return 1; (或result = 1; return 1;如果return不是局部变量。)

最好剪切并粘贴代码,以便我们可以将其剪切并粘贴到编辑器中,但基本上,goto Label_19之前的行需要转到中断线所在的位置。 中断之后的if语句需要变为else if,并且goto标签22可以变为中断(或像我之前的回答一样,将导致goto标签22的条件移动到for循环中)到for循环中。

PS:您的秘密对拥有可执行文件的任何人都不是秘密

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM