1. C# / Говнокод #20057

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    using Microsoft.VisualBasic.CompilerServices;
    using System;
    
    namespace ConsoleApplication2
    {
      [StandardModule]
      internal sealed class Module1
      {
        [STAThread]
        public static void Main()
        {
    label_0:
          int num1;
          int num2;
          try
          {
            ProjectData.ClearProjectError();
            num1 = 1;
    label_1:
            int num3 = 2;
            Test.TTT();
            goto label_8;
    label_3:
            num2 = num3;
            switch (num1)
            {
              case 1:
                int num4 = num2 + 1;
                num2 = 0;
                switch (num4)
                {
                  case 1:
                    goto label_0;
                  case 2:
                    goto label_1;
                  case 3:
                  case 4:
                    goto label_8;
                }
            }
          }
          catch (Exception ex) when (ex is Exception & (uint) num1 > 0U & num2 == 0)
          {
            ProjectData.SetProjectError(ex);
            goto label_3;
          }
          throw ProjectData.CreateProjectError(-2146828237);
    label_8:
          if (num2 == 0)
            return;
          ProjectData.ClearProjectError();
        }
      }
    }

    Вот какая жуть получилась при декомпиляции старого доброго On Error Resume Next из VB.
    Исходный код:
    Sub Main()
    On Error Resume Next
    TTT() 'определен в модуле Test
    Exit Sub
    End Sub

    Запостил: yamamoto, 23 Мая 2016

    Комментарии (16) RSS

    • Декомпиляторы не нужны.
      Ответить
      • Компиляторы не нужны. Царь в машинных кодах недурно пишет. Хотя трнсляторы все же не плохи, писать мнемоники удобнее
        Ответить
    • > Вот какая жуть получилась

      вы это называете жутью наверное потому что вам еще не приходилось выхлоп крестового компилера в дизассемблере расковыривать.
      Ответить
      • > выхлоп крестового компилера
        И уж тем более - читать ошибки на выхлопе крестового компилера, когда используется что-нибудь из буста...
        Ответить
        • их не надо читать -- методом исключения куда быстрее понять, в чём дело ^___~
          (при условии, что код твой)
          вот как быть, если бустоговно пролилось в чужом коде, я не представляю, даже не хочу думать об этом
          Ответить
    • попытался расковырять что происходит. по `num1` видно что компилер где-то на чем-то споткнулся: ставится в 1, и потом только сравнивается с 1. игры с num2 и num3 выглядят как последствия какой-то навороченной оптимизации.
      Ответить
      • num1 - флаг включения on error обработчика
        num2 - строка, на которую надо прыгнуть после ошибки (видимо, при on error goto N там было бы конкретное число, а на resume next туда ложат num3)
        num3 - номер стейтмента, который собирались выполнять, для resume next
        num4 - номер стейтмента, куда надо прыгнуть

        Строки 30-39 - табличка для прыжка на нужный стейтмент по его номеру (для каждой строки, 1 - на on error resume next, 2 - на Test.TTT(), 3 - на exit sub, на 4 - неявный выход?).

        num1 > 0U & num2 == 0 в строке 42 - "если включена обработка ошибок и строка не указана (resume next)".

        Как-то так, наверное.
        Ответить
        • ну как ты объяснил, так код сразу начал смысл иметь.
          Ответить
          • Ну не факт, что я правильно его распарсил. Надо больше примеров с разными on error.
            Ответить
    • goto из catch - это сурово. Шарпик реально позволит такое скомпилить обратно?
      Ответить
      • > catch (Exception ex) when (ex is Exception)
        Вот это тоже ахуенно.
        Ответить
    • Бггг... Прямо канонично! http://lurkmore.to/Goto
      Ответить
      • выхлоп декомпилера. if/while/etc - это все синтаксические подсластители для goto aka jump aka branch. потому что процы ничего кроме goto/jump/branch не умеют.
        Ответить
      • > http://lurkmore.to/Goto

        ...неожиданно, все очень правдоподобно: http://goo.gl/CQoHHp

        surprise buttsexcommon sense.
        Ответить

    Добавить комментарий