简体   繁体   English

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

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

My problem is not really a problem, but I want to make this code look a bit more elegant than it currently is. 我的问题并不是真正的问题,但是我想使这段代码看起来比现在的更优雅。 It has spaghetti code. 它具有意大利面条代码。

Here is a little example of what I got. 这是我得到的一个小例子。

 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;
}

What can I do to get rid of the labels without messing up the code flow as it's very important part of an encryption function? 我该怎么做才能摆脱标签的困扰而又不弄乱代码流,因为这是加密功能中非常重要的一部分?

Second answer, as the question changed a lot. 第二个答案,因为问题变化很大。

The original code looks like, after removing all redundant stuff: 删除所有多余的内容后,原始代码如下所示:

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

This is exactly the same as: 这与以下内容完全相同:

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

  DEF
}

Once you have done this rewrite, you could replace the goto LABEL_22 with a simple break . 完成此重写后,可以使用简单的break替换goto LABEL_22

EDIT: Or more explicitly: 编辑:或更明确地说:

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
}

The rule of thumb when you rewrite code like this is that the code should perform the same actions in the same order as before. 像这样重写代码时的经验法则是,代码应按照与以前相同的顺序执行相同的操作。 You simply can't move code around blindly, and to do this you must understand the flow of the code. 您根本不能盲目地移动代码,而要做到这一点,您必须了解代码流程。 In this case, when the first if is taken, the line I've marked with // 111 is first executed, then the line // 222 , nothing else. 在这种情况下,当采用第一个if时,将首先执行我用// 111标记的行,然后执行// 222的行。

The goto LABEL_1 is never executed, as there is no way out of the for loop. 永远不会执行goto LABEL_1 ,因为没有办法退出for循环。

Once this has been removed, you can replace goto LABEL_2 with a break , or even better simply return 1; 删除后,您可以将break替换为goto LABEL_2 ,甚至可以简单地return 1; (or result = 1; return 1; if return is not a local variable.) (或result = 1; return 1;如果return不是局部变量。)

It would be better if you cut and pasted the code so we can cut and paste it into an editor but basically the line before goto Label_19 needs to go where the break line is. 最好剪切并粘贴代码,以便我们可以将其剪切并粘贴到编辑器中,但基本上,goto Label_19之前的行需要转到中断线所在的位置。 The if statement following the break needs to become an else if and the goto label 22 can become a break (or move the conditional that leads to goto label 22 into the for loop as in my previous answer) into the for loop. 中断之后的if语句需要变为else if,并且goto标签22可以变为中断(或像我之前的回答一样,将导致goto标签22的条件移动到for循环中)到for循环中。

PS: your secret isn't a secret to anyone who has the executable PS:您的秘密对拥有可执行文件的任何人都不是秘密

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

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