Няшная / Говнокод #27345 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
#include <stdio.h>
#include <stdlib.h>

#define SPLICE(a,b) SPLICE_1(a,b)
#define SPLICE_1(a,b) SPLICE_2(a,b)
#define SPLICE_2(a,b) a##b


#define PP_ARG_N( \
          _1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9, _10, \
         _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
         _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
         _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
         _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
         _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
         _61, _62, _63, N, ...) N

/* Note 63 is removed */
#define PP_RSEQ_N()                                        \
         62, 61, 60,                                       \
         59, 58, 57, 56, 55, 54, 53, 52, 51, 50,           \
         49, 48, 47, 46, 45, 44, 43, 42, 41, 40,           \
         39, 38, 37, 36, 35, 34, 33, 32, 31, 30,           \
         29, 28, 27, 26, 25, 24, 23, 22, 21, 20,           \
         19, 18, 17, 16, 15, 14, 13, 12, 11, 10,           \
          9,  8,  7,  6,  5,  4,  3,  2,  1,  0

#define PP_NARG_(...)    PP_ARG_N(__VA_ARGS__)    

/* Note dummy first argument _ and ##__VA_ARGS__ instead of __VA_ARGS__ */
#define PP_NARG(...)     PP_NARG_(_, ##__VA_ARGS__, PP_RSEQ_N())

#define FIND_NONNULL_1(RES) \
  ((RES = (char *)(NULL)))

#define FIND_NONNULL_2(RES, VAR) \
  ((RES = (char *)(VAR)))

#define FIND_NONNULL_3(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_2(RES,__VA_ARGS__))

#define FIND_NONNULL_4(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_3(RES,__VA_ARGS__))

#define FIND_NONNULL_5(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_4(RES,__VA_ARGS__))

#define FIND_NONNULL_6(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_5(RES,__VA_ARGS__))

#define FIND_NONNULL_7(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_6(RES,__VA_ARGS__))

#define FIND_NONNULL_8(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_7(RES,__VA_ARGS__))

#define FIND_NONNULL_9(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_8(RES,__VA_ARGS__))

#define FIND_NONNULL_10(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_9(RES,__VA_ARGS__))

#define FIND_NONNULL_11(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_10(RES,__VA_ARGS__))

#define FIND_NONNULL_12(RES, VAR, ...) \
  (((RES = (char *)(VAR)) != NULL)?RES:FIND_NONNULL_11(RES,__VA_ARGS__))

// etc ...

#define FIND_NONNULLS_(N, ...) \
  SPLICE(FIND_NONNULL_, N)(__VA_ARGS__)

#define FIND_NONNULLS(...) \
({ \
  char *FIND_NONNULLS; \
  FIND_NONNULLS_(PP_NARG(FIND_NONNULLS, __VA_ARGS__), FIND_NONNULLS, __VA_ARGS__); \
  FIND_NONNULLS; \
})

char *side_effect_null(void)
{
  printf("!!null!!\n");
  return NULL;
}

char *side_effect_test(void)
{
  printf("!!test!!\n");
  return "test";
}

int main(void)
{
  printf( "result:%s\n", FIND_NONNULLS(0,side_effect_null(),0,side_effect_test(),0,0,side_effect_test(),"govno", side_effect_test()) );
  return EXIT_SUCCESS;
}

Это типа как short-circuit evaluation чтоб по цепочке хрень возвращающую строку вызывать, и там те функции хуйпойми сколько аргументов могут принимать (но там может быть константа, тогда естественно нихрена не надо вызывать) пока оно не вернет не-NULL. Как только вернуло не-NULL то вернуть это и дальше ничего не вызывать, а то там сайд эффекты всякие ненужные будут. А если не-NULL так и не нашло, вернуть NULL

Запостил: j123123 j123123, (Updated )

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

  • Реализуемо ли это крестопарашной шаблонометушней без использования препроцессора?
    Ответить
    • Шоблоёбло полно по тьюрингу, так что ответ – да, в теории.

      Касательно перспектив осуществления этого на практике, лучше обратиться к Полине =^~^=
      Ответить
      • То что оно полно по Тьюрингу еще не означает, что любую петушню им можно сделать. Например, шаблоносранью нельзя никаким образом получить AST некоторого класса и синтезировать новый класс, в котором такой-то метод и такие-то члены класса теперь отсутствуют, и такие-то типы таких-то членов класса теперь другие и идут в другом порядке.
        Ответить
        • Поскольку шалабаны тюрингполны, ты можешь написать на них лексер и парсер, и построить AST же
          Ответить
          • В принципе, на них потом можно это всё и скомпилировать. Итоговый бинарник, закодированный BASE-64 можно высрать в варнинге или онибке.
            Ответить
          • Только вот есть еще ограничения на то, что те шаблоны могут отрыгивать.
            Допустим, есть у тебя структура
            struct petuhi
            {
              int petuh;
              float plavuchi_petuh;
            };


            и допустим ты хочешь сделать структуру с переставленными первым и вторым полями, и приписать к ее названию слово "swap"
            struct petuhi_swap
            {
              float plavuchi_petuh;
              int petuh;
            };

            и чтоб это работало для произвольной структуры с произвольным набором аргументов (меняя при этом только положение первых двух полей), и делало структуру с именем, основанным на имени оригинала, приписывая в конце "_swap".

            Ну допустим ты передал в говношаблон тупо строку из исходника (опустим момент, как ты эту строку выковыривал):
            const char *shit =
            "struct petuhi\n"
            "{\n"
            "  int petuh;\n"
            "  float plavuchi_petuh;\n"
            "};\n"

            и это говно передаешь в шаблон
            И че с этим дальше делать? Он вообще умеет как-то читать строки? А может он умеет произвольную хуйню как бы вписать в исходник?
            Ну допустим можно взять констэкспр, и в компилтайме распарсить это говно и сделать компилтайм-строку с переставленной питушней, но как это вхуячить в исходник?
            Ответить
            • Как-то так это предлагалось делать в пропозале о метаклассах:
              constexpr {
                  for (const auto& field : compiletime_reverse(T$.fields)) {
                      -> { $field.type $field.name; }
                  }
              }
              Но я давно не следила, х.з. какой там прогресс сейчас.

              З.Ы. По-любому разрабы IDE уже плачут и пытаются отменить этот пропозал.
              Ответить
              • Давайте уже гомоиконность завезем, и вообще чтобы не было разницы между компайл таймом и рантаймом с точки зрения писания кода
                Ответить
                • Это так не работает. Сначала комитет примет 100500 частных случаев, посыпет их функциями Бесселя. И только потом начнёт обсуждать общий случай.

                  Там пи ещё не завезли, а ты уже гомоиконность хочешь...
                  Ответить
                  • Причём логичный, адекватный, внутренне непротиворечивый вариант не примут, потому что он не согласовывается с уже принятым частным случаем. Второй по адекватности не примут потому что противоречит другому частному случаю.
                    Ответить
                  • > Там пи ещё не завезли, а ты уже гомоиконность хочешь...

                    Наверное комитет не хочет завозить только pi. Надо еще и e завести. И почему только e и pi? Может завести вообще любые константы, ну чтоб например если мне понадобилась какая-то хуйня типа double myconst = sin(sqrt(pow(e, pi)) то чтоб у меня эта константа была с ммммммаксимально возможной точностью сгенерирована, чтоб там в компилтайме эта питушня делала вычисления с arbitrary-precision floating-point числами через какие-то ряды, и вписала мне самое точное приближение, которое можно хуйнуть в double.

                    Как долго комитет будет принимать такую поебень?
                    Ответить
                    • Надо еще чтоб гомоиконность генерить константы через численное интегрирование методом Монте-Карло в компилтайме, для этого надо чтоб ГПСЧ был в компилтайме с известным в компилтайме seed-ом, чтоб воспроизводимые сборки были.
                      Ответить
                      • Да сразу всю Maxima на constexpr'ы переписать, чтобы символьно диффуры решались. Т.к. Maxima на CL, заодно и гомоиконность подъедет.
                        Ответить
                        • > хэшем от __TIME__

                          Можно ещё кусок метушни зашифровать хешем от какой-нибудь даты в будущем.
                          Ответить
                    • Всё точно так! Ня данный момент предлагаемые константны выглядят так:
                      e - value of e
                      log2e - value of log2e
                      log10e - value of log10e
                      ln2 - value of ln2
                      ln10 - value of ln10
                      pi - value of π
                      inv_pi - value of 1/π
                      inv_sqrtpi - value of 1/√π
                      
                      sqrt2 - value of √2
                      
                      sqrt3 - value of √3
                      inv_sqrt3 - value of 1/√3
                      
                      egamma - value of Euler-Mascheroni γ constant
                      phi - value of golden ratio constant phi = (1+√5)/2
                      Ответить
                      • https://en.cppreference.com/w/cpp/numeric/constants - в C++20 они вроде как есть уже.

                        Только вот по какому принципу это все выбиралось? Почему inv_sqrt3 есть, но нет inv_sqrt2? Кому-то из стандартизаторов было очень нужно иметь 1/sqrt(3) как константу для какой-то математической хуйни, а вот 1/sqrt(2) ему не нужно было, и поэтому такой константы нет, или как это делается?
                        Ответить
                        • Да, так это и делается. Пишет кто-то proposal, где описывается что он хочет, нахуй это нужно, какие альтернативы есть и почему они — говно. И самое главное — дифф изменений к текущему стандарту. Это очень важно, потому что иначе на твой пропозал забьют хуй, если только кто-нибудь не захочет это всё прописать самостоятельно. Потом твою идею посылают нахуй, потому что она не стытуется с пунктом 13.1337.666.5, и ты выпускаешь следующию ревизию...

                          Например, пишет кто-то из Майкрософта предложение ввести константу 1,5, потому что у них много где она используется, и это было бы удобно. Оформляет это как надо, выносит на обсуждение. Там его забривают из Оракла, потому что они считают, что одной этой константы мало, а ещё нужно добавить '2', потому что они часто умножают на два. Потом подключается представитель ячейки программистов из Зимбабве и говорит, что им для денежных вычислений нужна константа '1000000000'. Все эти изменения вносятся, проходит голосование, всех устраивает, больше никому ничего не нужно, вносится в стандарт.

                          В результате, пи в стандарте не появляется, зато появляются охуенно нужные 1,5, 2 и 1000000000.
                          Ответить
        • > шаблоносранью нельзя

          Когда пропозал про метаклассы заедет -- можно будет.
          Ответить
    • В крестах всё хуёво с ленивыми вычислениями. Понадобится либо лямбда либо bind. Работать будет, но х.з. догадается ли конпелятор, что аргументы тут копировать не надо.
      Ответить
  • (s = side_effect_null()) || (s = side_effect_test()) || (s = "default";
    puts(s);


    Как-то так?
    Ответить
    • Да, типа этого. Только чтоб это удобнее записывалось через запятую без лишней питушни, и не делать временной переменной s.
      Ответить

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8