1. C++ / Говнокод #7867

    +171

    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
    char *f(char *s1, ...)
    { char **cp = &s1;            //--адрес первого указателя
       int len = 0;        
       // цикл для определения общей длины сцепляемых строк
       while (*cp) { len += strlen(*cp); cp++; }                          
      char *s = new char[len+1];       //--память для строки
      s[0]=0;                       //-- "очищаем" строку
    // цикл для сцепления строк
      cp=&s1;                       //-- опять установка на 1-й параметр
      while (*cp) 
      {  strcat(s, *cp);             //-- прицепляем первую (и следующие)
         cp++;                       //-- перемещаемся на следующую
      }         
      return s;
    }

    Сцепление строк (ноль в конце)
    http://www.rsdn.ru/forum/cpp/418970.1.aspx

    Запостил: rat4, 14 Сентября 2011

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

    • КРЕСТООСОБЕННОСТИ
      адепты Тараса ИТТ
      Ответить
    • >cp
      ЦЕНТРАЛЬНЫЙ ПРОЦЕССОР
      Ответить
    • показать все, что скрытоЖИРНЫЙ ШРИФТ С КАПСОМ - ОТНЫНЕ ВО ВСЕХ КОМЕНТАХ ДЛЯ С++ РАЗДЕЛА
      Ответить
    • А ПОЧЕМУ В КОММЕНТАРИЯХ //--? ЭТО ДЕКРЕМЕНТ ИЛИ ДЛЯ СОВМЕСТИМОСТИ С ЯЗЫКОМ ПРОГРАММИРОВАНИЯ АДА???
      Ответить
      • это просто слеши завалились
        Ответить
      • Да-да, это декремент комментария, в итоге получим "слабый" комментарий, который может быть рассмотрен компилятором. РАНДОМНО БЛЕАААТЬ
        Ответить
    • > s cp len
      КРЕСТОБЛЯ... Позвольте, но где здесь Ц┼┼???
      Ответить
      • Например, здесь:
        http://www.gamedev.ru/code/forum/?id=152263&page=4#m55
        >P. S. Ах, да точно, совсем забыл: На govnokod.ru не заносить! Copyright 2011
        Ответить
      • >new char[len+1];
        Нэ?
        Ответить
      • >где здесь Ц┼┼???
        char *s = new char[len+1];
        Ответить
    • СИШКОБЛЯДИ НЕ ОСИЛИВШИЕ СТЛ
      Ответить
      • На pure сишников гонишь? Они же не крестобляди и на паскаль перейти по своему желанию не могут. Есть компиляторы, например Paradigm С++ для микроконтроллера Beck, где нет STL.
        Ответить
      • Я твой stl шатал...
        Ответить
    • Нифига не говнокод - чел явно шарит в указателях и функциях с переменным числом параметров, такие знания говенкодить не дают. Кто будет мне минусовать пусть вывесит более пиздатое решение даной задачи.
      Ответить
      • >в указателях и функциях с переменным числом параметров
        >более пиздатое решение даной задачи
        смотри iostream или typesafe printf на шаблонах
        Ответить
      • А ничего, что аргументы могут располагаются в стеке в порядке уменьшения адресов? Псевдофункции va_* наверное по приколу сделаны?
        Ответить
        • __stdcall / __cdecl - есмъ наше все
          Ответить
          • Что ещё за __stdcall / __cdecl? Это на каком языке?
            Ответить
          • А с тем, что данные в стеке выравниваются, как бороться будем?

            И переменное количество параметров при stdcall вообще возможно?
            Ответить
            • >переменное количество параметров при stdcall вообще возможно?
              А почему бы и нет?

              >А с тем, что данные в стеке выравниваются, как бороться будем?
              Ну на то есть стандарт __stdcall..
              Ответить
              • В каком пункте Стандарта?
                Ответить
                • К стандарту С++ соглашения о вызовах не относятся, если что. Смотрите стандарт ABI.
                  Ответить
      • std::string f (std::vector<std::string> s);
        {
        ...
        };
        Ответить
        • f({"C++","0x","тарас?"});
          Ответить
          • Ну не знаю я, как типобезопасно и удобно передать в крестофункцию в С++ крестомассив переменной длины. Походу никак. В Аде и Дельфи это всё из коробки и очень удобно.
            Ответить
            • http://govnokod.ru/7867#comment107679
              Я комментом ниже показал.
              А также так, по старому стандарту:
              http://govnokod.ru/7867#comment107658
              Ответить
              • Решение в иострим-стиле не считается, так как в него нельзя передать готовый массив.
                Ответить
                • А в дельфи можно? Покажи.
                  Ответить
                  • function f(s: array of string: string);
                    begin
                    ...
                    end;

                    var
                    s1: array of string;
                    s2: array [1..4] of string;
                    const s3: array [1..5] of string = ('','','','','');
                    s: string;
                    begin
                    s := f(s1);
                    s := f(s2);
                    s := f(s3);
                    s := f(['1', '2', '3']);

                    В Аде это сделано ещё более удобно, вообще структурная парадигма в ней доведена до предела.
                    Ответить
                • >Решение в иострим-стиле не считается, так как в него нельзя передать готовый массив.
                  Что за вздор?
                  myfunc << myitem1 << myarray << myitem100500;
                  Ответить
            • Даже в праведном ANSI C есть как минимум два способа это сделать:
              1. Передать в функцию указатель на первый элемент и число элементов (здравствуй, функция main):
              int main(int argc, char *argv[]);

              2. Передать в функцию только указатель на первый элемент, и явно требовать от передающего, чтобы последним элементом был null (так, к примеру, делает гнушная функция getopt_long):
              char *s[] = {"a", "b", "c", null};
              char* f(char **args);
              Ответить
              • Ты пропустил слова "типобезопасно и удобно". Как хоть как-то передать, я и так знаю.
                Ответить
                • Не типобезопасно было бы если бы я использовал void*. А тут всё типа безопасно типобезопасно. Удобство дело субъективное. Более того, абсолютно любой подход к передаче неизвестного числа аргументов будет совпадать с одним из указанных с точностью до изоморфизма.
                  Ответить
                  • Способ номер один позволяет случайно передать не то число элементов. Какого хрена я должен при каждом вызове функции сам считать кол-во элементов в массиве?

                    Способ номер два это вообще лютый пиздец, неисчерпаемый простор для творчества взломщика.
                    Ответить
                    • Вопрос стоял именно в типобезопасности. С типами ведь нет никаких проблем.
                      В C есть бесконечное число способов накосячить. С этим никто не спорит.
                      Единственный выход из ситуации в C++, на мой взгляд - использовать массив, который знает свою длину (изоморфизм первого случая) или передавать связный список (изоморфизм второго случая), для которых определить соответсвующие конструкторы и позволить компилятору самому выполнить преобразование.
                      Ответить
                      • Только я не уверен, что преобразование будет совершать компилятор, а не программа при выполнении.
                        Ответить
                        • Хотите меня потроллить? =) Разумеется, конструктор будет выполняться в рантайме. Компилятор просто обернёт вызов
                          f({"a", "b", "c"});
                          в идеологически следующее
                          f(MySuperContainter<char*>({"a", "b", "c"}));
                          Ответить
                          • >Разумеется, конструктор будет выполняться в рантайме.
                            Компилятор С++ вполне может вызвать конструктор initializer_list из C++0x на этапе компиляции.
                            Для форсирования этого даже ключевое слово constexpr добавили на всякий случай, если компиль стугодумит, что б уж гарантированно...
                            Ответить
                            • интересно, а компилятор c++ умеет играть в шахматы...
                              Ответить
                              • Да, шаблоны С++ Тьюринг-полны, только пользовательского ввода нет. Так что играть сам с собой вполне может.
                                Ответить
                                • > Да, шаблоны С++ Тьюринг-полны

                                  Примерно, как брейнфак.
                                  Говорят, кто-то по приколу написал на крестошаблонах функцию вычисления детерминанта матрицы. Неплохо, да. Интересно, как на крестошаблонах выглядит функция, возвращающая вектор допустимых ходов в шахматах при заданной позиции. Такое тянет на диссертацию по КРЕСТОЗАДРОТСТВУ.
                                  Ответить
                                  • >кто-то по приколу написал на крестошаблонах функцию вычисления детерминанта матрицы.
                                    Шаблоны с float не работают чисто принципиально, чтобы таких задротов меньше было.
                                    Ответить
                                  • TarasB

                                    Это ещё ничего. Вон на лиспе, вообще часто самомодификацию программы во время выполнения используют и как то живут.

                                    С++ для тебя дедушка. Уважай. Переводи через дорогу и уступай место в трамвае.
                                    Ответить
                                    • Самомодификация - это сомнительно, а вот генерация исполняемого кода по ходу выполнения - это то, чего не хватает всем языкам.
                                      Ответить
                                      • >генерация исполняемого кода по ходу выполнения - это то, чего не хватает всем языкам
                                        Ага, например в PHP eval.
                                        Ответить
                                        • Ну скриптовые не считаем.
                                          Ответить
                                          • >Ну скриптовые не считаем.

                                            >а вот генерация исполняемого кода по ходу выполнения - это то, чего не хватает всем языкам.
                                            >всем языкам.
                                            >всем
                                            Ответить
                                            • Не придирайся к словам. И вообще, скриптовые языки - это не языки, ну ты понял.
                                              Ответить
                                      • >а вот генерация исполняемого кода по ходу выполнения - это то, чего не хватает всем языкам.

                                        Для того же C#, да и других языков есть много библиотек, кои это делают.
                                        Ответить
                                        • Только библиотеки делают это неоптимально. Они работают по принципу "хоть что-то". Почему нельзя вшить в код программы код компилятора, чтобы на ходу иметь доступ ко всем оптимизациям компилятора?
                                          Ответить
                                        • Да, вон недавно один умелец у нас генерил плоский код.
                                          Ответить
                                          • Генерил командами местного ассемблера. Херня.
                                            Надо, чтобы генерация кода была схожа по синтаксису с замыканиями.
                                            Ответить
                                            • Можно пример и подробные пояснения?
                                              Ответить
                                              • Ну про замыкания знаешь, типа

                                                type TIntFunction = function(i: integer): integer;

                                                function Adder(a: integer): TIntFunction;
                                                function Innerfunc(i: integer): integer;
                                                begin
                                                result := a+i;
                                                end;
                                                begin
                                                result := InnerFunction;
                                                end;

                                                Короче, этот код возвращает хитрожопый объект, который хранит указатели на функции, которые надо вызвать и параметры, которые надо в них подставить. А надо, чтобы она возвращала указатель на новый выполняемый участок памяти.
                                                Ответить
                                              • Ещё пример - аналог бустовского бинда.
                                                Есть функция f(x,y: integer): integer;
                                                Надо получить из неё новую, принимающуй один параметр. Второй фиксируем. Так вот, было бы удобно написать так:
                                                g := f(_, 2);
                                                Второй параметр зафиксировали на числе 2, первый - свободный. При этом, чтобы тело функции оптимизировалось с учётом знания второго параметра (это делается компилятором для констант).
                                                Короче, такая фигня. Я бы написал лучше, но в этой лесенки при такой ширине хуй что умное напишешь.
                                                Ответить
                                                • Это называется каррированием
                                                  Ответить
                                                  • Только оно везде возвращает просто объект, который внешне похож на нужную функцию, но на самом деле не является её, так как он не оптимизирован. Нужен именно возврат указателя на новый выполняемый участок памяти!
                                                    Ответить
                                                    • > новый выполняемый участок памяти!
                                                      Зачем? Не уронит ли это производительность из-за того, что новый исполняемый кусок, к примеру, ещё не в кэше?
                                                      Ответить
                                                      • Если эта функция потом будет прогнана 100 раз подряд, то нет. Да и вообще замыкания тормозят очень, так что в любом случае - нет.
                                                        Ответить
                                                    • >Нужен именно возврат указателя на новый выполняемый участок памяти!

                                                      Представляю себе исключение:
                                                      MemoryOverflowAtCompileTimeWhenCompileNe wFunctor

                                                      Это будет медленно при первом вызове. Да и реализация не тривиальная.

                                                      Запись в сегмент кода - сброс всего кеша кода.

                                                      Если уж у вас так много идей по оптимизации кода - напишите наконец свой компилятор.
                                                      Ответить
                                                    • >Только оно везде возвращает просто объект
                                                      Ох да, я пишу в объектно ориентированном стиле и возвращаю много объектов из функций. В чем проблема то? Когда это стало проблемой? Это регулярная операция уже оптимизирована по самое не могу. RVO, NRVO, RValueReference и много прочего.
                                                      Ответить
                                                  • С этой лесенкой хрен поймёшь, на какое сообщение этот комментарий.
                                                    Но в любом случае скажу, что кроме каррирования существует частичное применение - более мощный приём.
                                                    Ответить
                                                • >но в этой лесенки при такой ширине хуй что умное напишешь.
                                                  Перейди в конец треда и мы послушаем продолжение. А отсюда вставь ссылку на продолжение.
                                                  Ответить
                                                • Таки опять упомяну язык N. В нём частичное применение позволяет задать любой один или несколько параметров (хоть первый, хоть последний, хоть в середине).
                                                  Ответить
                                                  • В Scala вроде такая же возможность есть. А вот в Haskell нужны определённые телодвижения типа flip.
                                                    Ответить
                                                  • В крестах тоже есть буст двеоточие двоеточие бинд, но оно не создаёт функцию, оптимизированную под заданный параметр, оно просто подставляет параметр, ничего не оптимизируя.
                                                    Ответить
                                                    • В классических плюсах и так проблемы с опуханием объектного кода есть, подумаешь, лишний вызов функции... Вызов функций, особенно невиртуальных - вещь дешёвая.
                                                      Ответить
                                                      • Нет, не дешёвая по сравнению с вызовом функции, заточенной под определённое значение параметра. Знание компилятором одной константы может сильно оптимизировать код.
                                                        Ответить
                                                        • У вас какие то проблемы с нехваткой CPU? Эта ваша оптимизация не особо повлияет на критические к производительности участки кода, тк обычно их на лямбдах не пишут. А там где не особо нужно - ускорит, но зачем?
                                                          Ответить
                                                          • Особо критические участки могут не быть готовыми при запуске программы.
                                                            Ответить
                                                        • Проблема тарасовских лямбд в том, что после создания лямбды выделяют под свой код память, а потом её не освобождают. И в том же лиспе могут получатся бесконечное число "лямбд" с завидной регулярностью, что не слабо засрет память. А удалть их нельзя, тк каждый раз при компиляции вашей лямбды - нужно провести кучу оптимизаций, типа elemination constant expression и прочее. Такое создание лямбд будет занимать очень много времени, особенно если лямбду эту набили на пол программы, тк они видите ли очень оптимизируются...
                                                          Ответить
                                                          • Почему это нельзя удалять? Когда надо - берёшь и удаляешь.
                                                            Ответить
                                                            • delete lambda1; ? :D
                                                              Ответить
                                                              • Да, обычное освобождение памяти оператором delete, что тебя удивляет? Можно оборачивать в схаред_птр.
                                                                Ответить
                                                                • >Да, обычное освобождение памяти оператором delete

                                                                  Это не смешно.


                                                                  >Можно оборачивать в схаред_птр.

                                                                  Ага и каждый раз долго компилировать эти лямбды заново? А оптимизация при компиляции то не быстро идёт. Это тормознее динамических языков будет работать при активном использовании возвратом лямбд.
                                                                  Ответить
                                                                  • > Ага и каждый раз долго компилировать эти лямбды заново?

                                                                    Да. Что, скажешь, не бывает такого, когда число вызовов функции во много раз превышает число генераций функции?

                                                                    > Это не смешно.

                                                                    Да, это не смешно, это абсолютно нормально.
                                                                    Ответить
                                                                    • > это абсолютно нормально
                                                                      я так понял, проблема в том, что исполняемый код должен находиться в отдельном сегменте памяти, а new/delete работают с кучей.
                                                                      Ответить
                                                        • И хватит называть это лямбдами. То, о чем вы говорите - это замыкания и каррирование.
                                                          Ответить
                                            • Эх, в java можно генерить новый java-код только во время компиляции, а не во время исполнения.
                                              Ответить
                                              • > в java можно генерить новый java-код только во время компиляции, а не во время исполнения

                                                да ну?

                                                раз:
                                                http://www.javabeat.net/articles/73-the-java-60-compiler-api-1.html

                                                и еще вы обижаете разработчиков javassist: http://www.csg.is.titech.ac.jp/~chiba/javassist/
                                                Ответить
                                                • Да, что-то я ступил. JSP же :)
                                                  Ответить
                                                • В Java весь код, который можно генерировать на ходу, предопределён заранее. Можно заранее всё сгенерировать, и ничего не изменится. Так что Джава не считается.
                                                  Ответить
                                                  • угу, еще скажите, что Джава не считается, потому что результат работы программ тоже предопределен заранее
                                                    Ответить
                                                    • Ты либо троллишь, либо ваще не понял, о чём я.
                                                      Вользователь ввёл выражение, ты составил АСТ-дерево и хочешь сделать его функцией от иск. Оптимизированной функцией. Твот действия в Джаве?
                                                      Ответить
                                                      • тут даже ничего компилировать не надо, только парсить
                                                        Ответить
                                                      • А вводить-то пользователь выражение будет как? Текстом? Значит нужен парсер? А ещё желателен редактор кода с подсветкой и т. п. :)
                                                        Или пусть пользователь вводит выражения ТеХом.

                                                        Мои действия в C#: принять от пользователя текст, и передать его компилятору шарпа. Если не скомпилилось - вывести пользователю сообщение об ошибке, выданное компилятором. Если скомпилилось - юзаем полученную сборку. Работать она будет быстро, как и обычный дотнетный код.
                                                        Ответить
                                                        • Да, парсер надо писать самому. И передавать не текст, а логические структуры. А зачем подгонять логику программы под синтаксис?
                                                          Ответить
                                                  • Ну почему же. Можно написать генератор случайных программ. Можно компоновать и загружать классы, содержимое которых зависит от ввода пользователя. Так, к примеру, работает интерпретатор Scala.
                                                    Ответить
                                                    • > интерпретатор

                                                      Я говорю именно про настоящую компиляцию на ходу кода, для создания на ходу быстрых оптимизированных функций. Причём не того кода, который известен при запуске программы, а который определяется только из ввода пользователя.
                                                      Ответить
                                                      • Я запускаю интерпретатор, начинаю вводить выражения, определения функций, классов, трэитов... Каждое выражение прогоняется через компилятор, который генерирует байт-код (просто массив байтов). Байт-код загружается в виртуальную машину загрузчиком классов и выполняется. Все оптимизации выполняет JIT. Если не трудно, объясните различия.
                                                        Ответить
                                                        • Если в конце идёт компиляция, то это то, что надо.
                                                          Ответить
                • Шаблон-обёртка.
                  template <int n>
                  void f(char * a[n])
                  {
                      g(n, a);
                  }
                  Ответить
                  • А как сюда передавать массив длины, не известной при компиляции?
                    Ответить
                    • Если длина не известна на этапе компиляции, то известна в рантайме. Поэтому есть способы:
                      1) длина и указатель на первый элемент (C-style).
                      2) указатель на первый элемент массива, в котором последний элемент отмечен терминатором (C-string-style).
                      3) указатели на первый элемент и past-the-end (STL-style).
                      4) (ссылка на) весь STL-контейнер.
                      5) Range (Alexandresku-style).
                      Ответить
                      • 3) - это я так понимаю begin\end контейнера\массива?
                        5) - а это что за метод? не видел такого у Александреску что-то... Можно пример?
                        Ответить
                    • Есть один вариант ... вызывать компилятор из своего кода и запускать на выполнение результат :)
                      Ответить
            • [quiet]а вот в java...[/quiet]
              Ответить
              • Про Оберон ещё расскажи, говорят, в нём всё мегакруто.
                Ответить
                • Дык java это и есть оберон, испорченный сишным синтаксисом и всяким задротством типа дженериков
                  Ответить
                  • Вы прямо как Вирт излагаете
                    Ответить
                    • Да, это была стилизация. Я рад, что вы заметили :)
                      Ответить
                      • Порадовали надписи Water, JavaBeans, Control на фото кофеварильни xD
                        Ответить
                        • Из-за этого агрегата я стал пить крепкий кофе 6-8 раз в день.
                          Ответить
                          • Ой, я бы так не смог. Так, чаек легонький.
                            А судя по фоткам у вас неплохо оборудовано рабочее место. Неужели необходимо такое количество кофе?))
                            Ответить
                            • Уж больно кофе вкусный. Что ещё делать, пока 5 минут запускается tomcat? =) да и работать приходится много, часов по 10-12.
                              Ответить
                              • Остается только завидовать.
                                А вообще - попробуйте цикорий. Вкус примерно тот же, а вот содержание более щадящее для организма.
                                Ответить
              • Так что там в java?
                Ответить
                • void f(String... args) {
                      for (String arg : args) {
                          doSomething(arg);
                      }
                  }
                  Ответить
                  • Кошерно.
                    Ответить
                    • Массив же не передать. Тарас будет не доволен.
                      Ответить
                      • можно передать массив. На самом деле String... это фактически String[]. f можно вызывать так:
                        f("java", "not", "so", "bad");
                        f(new String[] {"java", "sucks"});
                        f(someArrayReference);
                        Ответить
                        • Ясно. А произвольный контейнер можно, как в С#?
                          Ответить
                          • Только с явным приведением типа (осторожно, магия):
                            f(list.toArray(new String[] {}));
                            Ответить
                            • А печему не list.toArray()?
                              Ответить
                              • Магия дженериков. toArray() возвращает Object[], код не скомпилится. Если привести тип к String[], код упадёт в рантайме. А вот когда на входе toArray() есть массив нужного типа, метод сможет понять, какого именно типа должен быть возвращаемый массив. Хреново конечно, что компилятор в этой ситуации не выводит нужный тип в зависимости от контекста.
                                Ответить
                                • >Магия дженериков.
                                  >Object[],
                                  В C# такой траблы нет. Дженерики в сишарп возвращают реальный тип. никаких лишних приведений.
                                  Ответить
                                  • трабла в том, что дженерики теряются в рантайме и становятся Object. Какой был дженерик - в рантайме не узнать, можно только узнать тип реально переданных аргументов - вот тут как раз тот случай.

                                    Такое извращение было сделано, чтобы байткод Java 5+ был 100% совместим с байткодом Java 5-
                                    Ответить
                                    • и ещё чтобы не создавать новый байткод для списка только из-за того, что у него поменялся тип содержимого.
                                      Ответить
                                      • нуу, разработчики могли бы пойти и путем С++, т.е. использовать перегрузку
                                        Ответить
                            • >Только с явным приведением типа
                              Это затратная для контейнеров O(n) операция. Глупо. Тем более с двойной затратой памяти.

                              В C# без затрат CPU:
                              void f(params List<String> args) {
                                  foreach (var arg in args) {
                                      doSomething(arg);
                                  }
                              }
                              Ответить
                              • Я всего лишь излагаю факты, а не предлагаю инженерные решения. Вообще в java принято использовать коллекции, а не массивы.
                                Ответить
                                • Принято использовать коллекции, а "String..." представляет из себя массив. Где логика?
                                  Ответить
                                  • Спросите у разработчиков java. Оптимизация, наверное. Такие методы в 99% случаев используются там, где разработчик будет явно перечислять аргументы, а не пихать коллекцию (format(), LOG.error(), etc.).
                                    Ответить
                                    • >Оптимизация, наверное.
                                      Точно не скорости исполнения.
                                      Ответить
                                      • Мне кажется, это мелочи. Я уже не помню, когда мне последний раз приходилось писать методы с переменным числом параметров. А если бы и пришлось, то массив бы меня более чем устроил.
                                        Ответить
                                    • связано это еще и с тем, что бы не создавать сложностей. Например, хорошей практикой считается передача не конкретного типа, а интерфейса. И вот, скажем, передаем вараргсы такому методу - и как ему с ними обращаться, что это? Vector, ArrayList, а, может, BlockingDeque? все было бы чревато побочными эффектами
                                      Ответить
                                      • Iterable?
                                        Ответить
                                      • >практикой считается передача не конкретного типа, а интерфейса
                                        Проблемы Java такие же как и у С++. Поддержание наследственности. Толи в сишарп передал интерфейс:
                                        void f(params IEnumerator<string> args) {
                                            foreach (var arg in args) {
                                                doSomething(arg);
                                            }
                                        }
                                        и никаких тебе String... с его String[]. И теперь можно сувать любые контейнеры.
                                        Ответить
                                        • ну точно также в Java можно передать Iterable
                                          Ответить
                                        • Очередной холивар из-за какой-то херни.
                                          Вот чего в java действительно очень не хватает - функции как объекты первого рода. Объявление анонимного класса обычно занимает больше места, чем заключённая в его реализацию логика. Вот это реально бесит.
                                          Ответить
                                          • Даёшь в java лямбды, перегрузку операторов и нормальные генерики!
                                            Ответить
                                            • Лямбды будут в восьмёрке, надеюсь, обратная совместимость будет сохранена, иначе мы их не увидим в промышленных проектах ещё лет пять. Дженерики в принципе адекватны с учётом выбранной идеологии, а вот вывод типов можно было бы сделать и поумнее.
                                              Ответить
                                          • т.е. this.addClearListener({this.list.clear() ;}) ?
                                            да, пожалуй.
                                            Ответить
                                            • Для сравнения то, что приходится писать каждый день:
                                              ReportDto reportDto = Iterables.find(
                                                              getAddressDto().getReports(),
                                                              new Predicate<ReportDto>() {
                                                                  public boolean apply(ReportDto dto) {
                                                                      OrderEntity orderEntity = dto.getOrder();
                                                                      return (orderEntity != null) && Objects.equal(oid, orderEntity.getOid());
                                                                  }
                                                              }, null);

                                              мясо.
                                              Ответить
                                              • точно, визуально теряется смысл. Могу посоветовать груви - там плюшек много, а байткод тот же, библиотека - тоже общая
                                                Ответить
                                                • Groovy нельзя, всё на java. К тому же, груви слишком тормозной (у нас проект и так 5 минут на tomcat стартует). Вот Scala - это наиболее реальный выход из проблемы. Скорее бы начали переходить на Scala, уже не терпится завязать с этим вынужденным говнокодерством.
                                                  Ответить
                                                  • почему это слишком тормозной?

                                                    > Вот Scala - это наиболее реальный выход из проблемы
                                                    ага, и playframework
                                                    Ответить
                                  • В том, что массивы в Java статические - их удобно использовать "только для чтения", в т.ч. для итераций.
                                    Коллекции же реализуют интерфейс Collection и являются динамическими, но их довольно много, и непонятно, какой нужен бы для varargs. Вот и выбран путь "наименьшей сложности"
                                    Ответить
                                    • >В том, что массивы в Java статические - их удобно использовать "только для чтения"
                                      А для записи не удобно? (:
                                      Ответить
                                      • чаще всего нет, особенно в том случае, если размер заранее неизвестен. а изменение размера массива в Java дело хлопотное: выделить новый массив, скопировать элементы старого, избавиться (по желанию) от старого массива, обновить все указания со старого на новый
                                        Ответить
                                        • Inplace сортировка уже не в моде? Можно для записи использовать массивы.
                                          А вот использовать массивы для алгоритмов, требующих расширение контейнера, очень глупо.
                                          Ответить
                                          • вернемся к varargs: как правило, их не нужно расширять или как-то перезаписывать, хотя извращенцы технически могут это делать
                                            Ответить
                                            • >varargs, их не нужно перезаписывать
                                              А почему бы и нет? Сортировка без лишнего копирования 100500 элементов? Вроде не плохо. А в varargs функцию вполне могут передать массив с таким кол-вом элементов. Например, тарас так сделает.
                                              Ответить
                    • C#:
                      void f(params String[] args) {
                          foreach (var arg in args) {
                              doSomething(arg);
                          }
                      }
                      Массив передаётся в придачу, кроме просто множества параметров. А можно и другие виды контейнеров.
                      Ответить
        • string f (initializer_list<string> s);
          {
          ...
          };
          Ответить
    • >Только оно везде возвращает просто объект
      > Ох да, я пишу в объектно ориентированном стиле и возвращаю много объектов из функций. В чем проблема то? Когда это стало проблемой? Это регулярная операция уже оптимизирована по самое не могу. RVO, NRVO, RValueReference и много прочего.

      А я не про это. А про то, что вызов такой хитрожопой функции (которая на самом деле хрен знает что) будет куда медленнее, чем вызов настоящей функции.
      Ответить
      • Не намного дольше, чем вызов виртуального метода класса и вызов обычного метода класса.
        Ответить
        • А что, это быстро? А сборка функции из простых не путём набора вектора из указателей на них, а путём подстановки - это на 2 порядка ускоряет вызов f(x), составленной, как замыкание, из сложений, вычитаний и умножений. Я как бы замыкания на скорость проверял, результат меня удручил.
          http://forum.pascal.net.ru/index.php?showtopic=28513
          Ответить
          • > замыкания на скорость проверял
            А у вас нет результатов бенчмарков замыканий для менее специфичных языков? Java-аналоги замыканий ничем не отличаются от остальных объектов, только несколько ограничены в возможностях и требуют громоздких конструкций.
            Ответить
            • Нету. Я там же проверил на скорость свой байткод, тоже тормоз. Сделать что-то быстрее этого байткода, без компиляции на ходу, уже нельзя.
              Ответить
    • > Представляю себе исключение:
      > MemoryOverflowAtCompileTimeWhenCompileNe wFunctor

      Ну и что?

      > Это будет медленно при первом вызове.

      Да.

      > Да и реализация не тривиальная.

      Вшить в программу компилятор и байт-коды функций.

      > Запись в сегмент кода - сброс всего кеша кода.

      Ничего.

      > Если уж у вас так много идей по оптимизации кода - напишите наконец свой компилятор.

      У меня нет ресурсов для этого.
      Ответить
      • >У меня нет ресурсов для этого.
        Мозг есть, руки есть, компьютер есть. Или я ошибся по всем 3м пунктам?
        Ежегодно тысячи дипломников пишут свои компиляторы или интерпретаторы. Последуй их дорогой и обгони. Сделай сам дельфи своей мечты.
        Знаю сложно, но те кто не тратят время и не плачутся на говнокоде о недостатках всех компиляторов мира и мира в целом - добиваются успеха. Тем более тебе любые велосипеды по колено, если вспомнить твои недавние заявления.
        Ответить
        • Софтрендер - это одно, компилятор нового языка - это другое.
          Кроме мозга, рук и компьютера, нужно время (3 месяца) и скорость, чтобы в это время уложиться. Если не уложиться - интерес пропадает, проект забрасывается.
          Я не уложусь, даже если воспользуюсь помощью gcc.
          Ответить
          • Всё-таки я никак не пойму до конца, что тебе нужно.
            Если новый код должен ввести пользователь в процессе работы программы, и этот код может быть сколь угодно сложным (не просто пара арифметических операций над парой чисел, что можно реализовать с помощью пары чекбоксов и т. п,), то самый быстрый и простой способ: пусть вводит код текстом. А этот текст передаём компилятору. Тот же Tiny C Compiler можно использовать. А потом, после компиляции, можно использовать полученную программу. Работать она будет быстро, без всяких издержек на виртуальные вызовы и т. п.
            Ответить
            • По-моему, всё довольно прозрачно: Тарасу не нравится, что в его Адском коде closure работают в два раза медленнее (судя по постам в приведённом им источнике, они вообще работают только при специфическом наборе флагов компиляции), что, вероятно, плохо отражается на общей производительности программ на его Celeron 600MHz. Поэтому он их не использует. А хотел бы.
              Ответить
              • Петросян, залогинься
                Ответить
                • По-моему, я всё довольно точно описал. Минусовать комменты своих собеседников - первый признак баттхёрта =)
                  Ответить
                  • Ты забыл дописать
                    Я ВСЕХ ВАС ТРОЛЛЮ У ВАС У ВСЕХ БАТТХЁРТ

                    Минусовать не я первый начал.
                    И вообще, тут серьёзные вещи обсуждают, а ты херню мелешь, если тебе тема неинтересна, то чего пришёл тогда.

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

                      > тут серьёзные вещи обсуждают
                      Пока я никаких серьёзных вещей не увидел. Ты пишешь про замыкания и частичные применения, а в том же Haskell это настолько обычная и часто используемая вещь, что никто даже не задумывается о том, что втыкать в каждый бинарник компилятор.
                      Вот когда у тебя будет рабочий прототип с бенчмарками, доказывающими, что твои замыкания круче всего того, что уже есть - тогда можно говорить о какой-то серьёзности. Пока всё на уровне [code=blue]http://govnokod.ru/7746[/color]
                      Ответить
                      • > Ты пишешь про замыкания и частичные применения,

                        Я говорю про их реализацию через компиляцию по ходу выполнения, а не через тормозную эмуляцию. Только не надо говорить, что это якобы не надо. Надо.
                        Ну и ещё я говорю про компиляцию на ходу не через текст (это кривизна), а через замыкания и частичное применение. Одно с другим соединить, короче.

                        > Вот когда у тебя будет рабочий прототип с бенчмарками, доказывающими, что твои замыкания круче всего того, что уже есть - тогда можно говорить о какой-то серьёзности.

                        Это уже чистый троллинг. А в спорах об автомобилях ты тоже говоришь что-то типа "собери свой автомобиль, а потом спорь"?

                        > и уж точно не я. я своих собеседников никогда не минусую

                        А, ну извини тогда.
                        Ответить
                        • > Это уже чистый троллинг.
                          Нет, друг мой, всё не так. Просто я вижу, что дальше разговоров дело не зайдёт. Поэтому относиться к этому серьёзно очень сложно (как вообще ко всему, что происходит на ГК).
                          Линус вон не ходил по форумам и не троллил, а сидел и ваял свою ось, потому что существующие его не устраивали. В итоге он на коне.
                          Ответить
                          • Ты всерьёз считаешь, что у меня других дел нету и что у меня 24/7 свободного времени?
                            Ответить
            • > пусть вводит код текстом. А этот текст передаём компилятору

              Это кривизна. Надо, чтобы передавался не текст, а логические структуры.
              А для передачи текста надо, чтобы программа помнила имена своих переменных и функций.
              Синтаксис определенения замыканий и частичного применения больше подходит.
              Ответить
              • Никода не думал нагенерить столько кода, сколько нужно для оптимизации ещё на этапе компиляции, а не генерить код в авральном режиме после запуска программы?
                Ответить
                • Нагенери нужное кол-во кода при компиляции для быстрого вычисления f(x), f зависит от ввода пользователя.
                  Ответить
                  • Ну а разбить функцию на более атомарные и подставлять их?
                    Ответить
                    • Ну разбил я функцию на +,-,*,/, дальше что? В лучшем случае будет последовательность вызовов по указателю. Нет, это на 2 порядка медленнее, чем последовательность честных вызовов.
                      Ответить
                      • Если ты где то что то там нагенерил после создания программы - это в любом случае будет вызов по указателю.
                        Ответить
                        • Да, но один вызов суперфункции по указателю - это дешевле, чем последовательность таких вызовов.
                          Ответить
                  • Разбить f на элементы, которые не зависят от ввода пользователя и сгенерить их на этапе компиляции. С++/lisp с этой задачей успешно справляются.
                    Ответить
                    • Тем более, lisp, который прекрасно подходящий для подобного рода задач, компилится в нативный код с незапамятных времён. Но Тарасу это не подойдёт, ведь это медленне, чем "оптимизированные лямбы".
                      Ответить
                      • Да lisp можно использовать для генерации кода уж после запуска программы. Тарас, используй - не хочу. Делай свою библиотеку оптимизированных лямбд.
                        Ответить
                        • Я не помню, почему мне он не понравился. С типизацией какие-то глюки были, нет?
                          Ответить
                          • > типизацией какие-то глюки
                            Глюков нет. Там динамическая типизация.
                            Ответить
                            • >Глюков нет. Там динамическая типизация.
                              Значит глюки переходят на этап выполнения
                              Ответить
                              • С динамической типизацией в лиспе глюков выходит меньше, чем со статической в сях
                                Ответить
                            • Да-да, я про это.
                              Ответить
                    • Как ты эти элементы объединишь на этапе выполнения, расскажи.
                      Ответить
                      • Переносим все параметры функции f, какие возможно в параметры шаблона.

                        Та функция, что ты декомпозируешь:
                        f<10050 шаблонов типов и данных>();

                        Внутри этой функции ты вызываешь отдельные элементы функции f<...>(): f1<over 900 шаблонов>() f2<...>(), f3 , f i (все возможные параметры функций переносишь в шаблоны)

                        Дальше создаешь массив функций f с различными специализациями шаблона этой функции.

                        Массив в n размерностей этих самых f специализаций шаблона. Для очень сложных случаев, где параметры нельзя представить индексом - юзаешь map/hash. Для софтрендера достаточно массива.

                        Так даже твой софтрендер очень хорошо бы декомпозировался. Меняем какие то параметры рендернинга и перед тем как начинаем рисовать - сохраняем адрес функции в указатель из этого массива n размерности. Выборка из этого массива осуществляется по параметрам функции. Дальше для каждого треугольника вызываем эту шаблонную функцию из указателя почти без параметров и оптимизированную до максимума (компилятором убираются все условные переходыб разворачиваются на полную циклы по источникам света\текстур, проводится по всем параметрам функции constant expression elimination, тк они шаблонные, все вызовы f i'тое<>() встраиваются компилятором, тк шаблонные и тд. __forceinline можно даже.)

                        То есть от кол-ва текстур\источников света уже зависимости не будет (циклы по ним развернуты, если нужно). От прочих параметров, типа Z_Test_Enabled тоже не зависит. То есть теперь есть зависимость только от текстур\динамических источников света и адреса результирующей поверхности рендернинга.

                        Фактически это вынос проверки всех условий наружу цикла, да и то это не проверка, а обращение к массиву по индексу один раз до цикла.

                        Опять же шаблонами можно разворачивать циклы форсированно. Да и вообще это такая штука, что очень сильно можно использовать для оптимизации.
                        Ответить
                        • Шаблоны что-либо оптимизируют только при компиляции. Они вообще в некоторые языках на букву "цэ английское" работают только при компиляции.
                          Ответить
                          • >Шаблоны что-либо оптимизируют только при компиляции.
                            Я об этом же. Но результат не слабый в рантайме.
                            Ответить
              • Угу. Наконец-то я всё понял. Долго я тупил...
                Значит, нужно связывать получаемый от пользователя код с уже имеющимся. На это способен Expression. Повторю ссылочки, которые приводил в другой теме, может кому пригодится:
                http://msdn.microsoft.com/ru-ru/library/system.linq.expressions.expression.aspx
                http://msdn.microsoft.com/en-us/library/bb397951.aspx
                Да, это .NET. Но в других языках/платформах ничего гибче я не знаю. Если устроит разработка под .NET, то именно это и рекомендую. По скорости итоговый код всяко будет быстрее лиспового (ибо там динамическая типизация и вообще...). Лисперов прошу камнями не кидаться, ибо я сам его нежно люблю, и периодически смахиваю пыль с DrRacket, на котором изредка пописываю (это реализация Scheme).

                Остаётся решить проблему с парсером. На .NET решение есть простое: Nemerle.PEG. Скажу лишь, что парсер языка C# был написан на PEG одним человеком за месяц. Парсер ВСЕГО языка (правда, без unsafe)! А уж парсер простого специализированного языка, заточенного под конкретные нужды будет в разы проще. Если имеешь понятие о lex/yacc etc, или хотя бы о регулярках, то написание парсера будет простым делом. Причём в отличие от регулярок PEG не только write-only, но и читается легко. По скорости опять же рвёт регулярки в клочья. Опять же, писать легко, ибо подсветка синтаксиса прямо в коде парсера и прочие плюшки.

                По сути, имеется лишь один глобальный недостаток: это .NET, что не всех устроит.
                Ответить
                • >Nemerle.PEG. Скажу лишь, что парсер языка C# был написан на PEG одним человеком за месяц
                  Перед тем, как продать его Майкрософту?
                  Интересно, каким парсером пользуются сейчас создатели языка C# для оного в современном виде?
                  PEG есть только для немерле?
                  Ответить
                  • Посмотрел, спасибо.
                    1 ый вопрос: Сами немерловцы написали и никакого отношения к майкрософтовскому сишарпу нет.
                    3 ий вопрос - глупый.
                    Ответить
                • Пишут, что Nemerle.PEG разбирает текст любого языка за линейное время. о_О
                  Ответить
                  • Ну любого - это вряд ли, но арифметическое выражение перевести в АСТ-дерево, например, за линейное делается. Что-то сложнее не делал, но, думаю, принцип тот же.
                    Ответить
                • Посмотрел ссылки. Я так понял, что Expression-что-то типа АСТ-дерева. То есть можно по ходу выполнения собрать АСТ-дерево передать точканетовскому компилятору? Это уже неплохо.
                  Ответить
    • В очередной раз убеждаюсь, что при превышении 100 комментов к ГК следить за ними становится совершенно неудобно.
      Ответить
      • И лесенка 15 ступенек максимум (
        Ответить
        • Это больше, чем в большинстве многоквартирных домов.
          Ответить
        • Кстати:
          Число подъемов в одном марше между площадками (за исключением криволинейных лестниц) должно быть не менее 3 и не более 16. В одномаршевых лестницах, а также в одном марше двух- и трехмаршевых лестниц в пределах первого этажа допускается не более 18 подъемов.
          СНиП 2.08.02-89. Общественные здания и сооружения.

          А как в жилых домах, не знаю. Надо гуглить.
          Ответить
    • *мысли в слух*
      Кстати, мне кажется, что оценки типа "+1" не очень информативны. Лучше бы выводить более подробную информацию типа "+5 -4" типа пятеро за, четверо против. А то не всегда понятно - всем похер или мир разделился пополам :)
      Ответить
      • учитесь иногда пользоваться мышкой тоже, подводите ее к оценкам ;-)
        Ответить
        • Блин, а я и не знал. Круто, теперь буду пользоваться этой фичей :)
          Ответить
      • а сначала я уж было подумал, что вы ратуете за [5]v [оригинальность]v --т.е. не просто +\-, а оценка - и с причиной. ([]v - это комбобокс схематически)
        Ответить
      • Наведи мышку на оценку: появится количество за и против ;)
        Ответить
        • Лучше б оно было по дефолту видно
          Ответить
          • с логинами голосовавших ;)
            Ответить
            • На кой такая свистоперделка?
              Ответить
            • тогда я буду голосовать от гуеста



              сраказм
              Ответить
            • и ключами от квартиры, где деньги лежат:)
              Ответить
              • Ага и в кабинке на крышке унитаза выводить список самых злых врагов выбранного пользователя.
                Тех, кто минусует его комментарии больше и плотнее остальных.
                А также однокакашников - тех, кто плюсует.
                Еще ввести фрэнд ленту, добавить награждение за самое большое количество однокакашников и награждать победителей подписью с рисунком понега до следующего подсчета результатов (например, проводить подсчет каждую неделю)
                И запилить блять чатик
                Ответить
                • с игнором и смайликами чмоками?
                  Ответить
                • Почему, интересно, кто поставил "минус" - сразу враг?
                  Я воспринимаю это как моё личное отношение к сообщению, но не к автору. Если автор мудак, и получает много и часто - это только его проблемы.

                  К счастью, тут "карма" ни на что не влияет.
                  Ответить
                  • Кхкхм...потому что это СПААААРТАААААААААА

                    если вы не заметили, я не предлагаю сделать врагом каждого, кто минусанул, а только тех, количество минусов которых перешло через какой-либо разумно подобранный порог.
                    Херня это все, конечно, но ведь спарта жеж =0
                    Ответить
                    • у троллей враги - весь гк... и все -- лучшие друзья страйко )))
                      Ответить
                      • Ну, то, что у страйко вся крышка будет под хохлому я догадывался
                        Ответить
                        • Ну не скажи. Я как-то минуснул одно сообщение Страйко. (До сих пор боюсь...) :D
                          Ответить
            • Если честно, мне не раз приходила в голову такая мысль :)
              Как ни крути, а общение на этом ресурсе является главной составляющей...
              Ответить
    • Увлекательная подработка в домашних условиях за компьютером.
      Мы предлагаем: Достойная зарплата без задержек, справка 2-НДФЛ, карьерный рост, бесплатное обучение,
      свободный график, страховые взносы в Пенсионный фонд, официальный договор (по желанию).
      График работы, Вы определяете самостоятельно, по своим возможностям.
      Ваш возраст и образование значения не имеют.
      Обязательные условия: наличие компьютера и интернета.
      Ваши действия:
      1. На сайте ( www.off-rabota.tk ) скачайте и установите приложение.
      2. Ознакомьтесь с содержимым.
      3. Пройдите несложную регистрацию.
      4. Обязательно, пройдите курсы обучения. (Бесплатно)
      5. Начинайте зарабатывать!
      Зарплату мы перечисляем только на банковскую карту любой платёжной системы.
      (Для работы советуем оформить отдельную карту)
      ВНИМАНИЕ! Весь процесс регистрации, обучения совершенно бесплатны. Не попадитесь в руки мошенников!
      Ответить
      • я бы с радостью, но у меня нет компьютера, к сожалению
        Ответить

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