- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 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;
}
адепты Тараса ИТТ
ЦЕНТРАЛЬНЫЙ ПРОЦЕССОР
КРЕСТОБЛЯ... Позвольте, но где здесь Ц┼┼???
>P. S. Ах, да точно, совсем забыл: На govnokod.ru не заносить! Copyright 2011
Нэ?
>более пиздатое решение даной задачи
смотри iostream или typesafe printf на шаблонах
И переменное количество параметров при stdcall вообще возможно?
А почему бы и нет?
>А с тем, что данные в стеке выравниваются, как бороться будем?
Ну на то есть стандарт __stdcall..
{
...
};
Я комментом ниже показал.
А также так, по старому стандарту:
http://govnokod.ru/7867#comment107658
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']);
В Аде это сделано ещё более удобно, вообще структурная парадигма в ней доведена до предела.
Что за вздор?
1. Передать в функцию указатель на первый элемент и число элементов (здравствуй, функция main):
2. Передать в функцию только указатель на первый элемент, и явно требовать от передающего, чтобы последним элементом был null (так, к примеру, делает гнушная функция getopt_long):
Способ номер два это вообще лютый пиздец, неисчерпаемый простор для творчества взломщика.
В C есть бесконечное число способов накосячить. С этим никто не спорит.
Единственный выход из ситуации в C++, на мой взгляд - использовать массив, который знает свою длину (изоморфизм первого случая) или передавать связный список (изоморфизм второго случая), для которых определить соответсвующие конструкторы и позволить компилятору самому выполнить преобразование.
Компилятор С++ вполне может вызвать конструктор initializer_list из C++0x на этапе компиляции.
Для форсирования этого даже ключевое слово constexpr добавили на всякий случай, если компиль стугодумит, что б уж гарантированно...
Примерно, как брейнфак.
Говорят, кто-то по приколу написал на крестошаблонах функцию вычисления детерминанта матрицы. Неплохо, да. Интересно, как на крестошаблонах выглядит функция, возвращающая вектор допустимых ходов в шахматах при заданной позиции. Такое тянет на диссертацию по КРЕСТОЗАДРОТСТВУ.
Шаблоны с float не работают чисто принципиально, чтобы таких задротов меньше было.
Это ещё ничего. Вон на лиспе, вообще часто самомодификацию программы во время выполнения используют и как то живут.
С++ для тебя дедушка. Уважай. Переводи через дорогу и уступай место в трамвае.
Ага, например в 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, первый - свободный. При этом, чтобы тело функции оптимизировалось с учётом знания второго параметра (это делается компилятором для констант).
Короче, такая фигня. Я бы написал лучше, но в этой лесенки при такой ширине хуй что умное напишешь.
Зачем? Не уронит ли это производительность из-за того, что новый исполняемый кусок, к примеру, ещё не в кэше?
Представляю себе исключение:
MemoryOverflowAtCompileTimeWhenCompileNe wFunctor
Это будет медленно при первом вызове. Да и реализация не тривиальная.
Запись в сегмент кода - сброс всего кеша кода.
Если уж у вас так много идей по оптимизации кода - напишите наконец свой компилятор.
Ох да, я пишу в объектно ориентированном стиле и возвращаю много объектов из функций. В чем проблема то? Когда это стало проблемой? Это регулярная операция уже оптимизирована по самое не могу. RVO, NRVO, RValueReference и много прочего.
Но в любом случае скажу, что кроме каррирования существует частичное применение - более мощный приём.
Перейди в конец треда и мы послушаем продолжение. А отсюда вставь ссылку на продолжение.
Это не смешно.
>Можно оборачивать в схаред_птр.
Ага и каждый раз долго компилировать эти лямбды заново? А оптимизация при компиляции то не быстро идёт. Это тормознее динамических языков будет работать при активном использовании возвратом лямбд.
Да. Что, скажешь, не бывает такого, когда число вызовов функции во много раз превышает число генераций функции?
> Это не смешно.
Да, это не смешно, это абсолютно нормально.
я так понял, проблема в том, что исполняемый код должен находиться в отдельном сегменте памяти, а new/delete работают с кучей.
да ну?
раз:
http://www.javabeat.net/articles/73-the-java-60-compiler-api-1.html
и еще вы обижаете разработчиков javassist: http://www.csg.is.titech.ac.jp/~chiba/javassist/
Вользователь ввёл выражение, ты составил АСТ-дерево и хочешь сделать его функцией от иск. Оптимизированной функцией. Твот действия в Джаве?
Или пусть пользователь вводит выражения ТеХом.
Мои действия в C#: принять от пользователя текст, и передать его компилятору шарпа. Если не скомпилилось - вывести пользователю сообщение об ошибке, выданное компилятором. Если скомпилилось - юзаем полученную сборку. Работать она будет быстро, как и обычный дотнетный код.
Я говорю именно про настоящую компиляцию на ходу кода, для создания на ходу быстрых оптимизированных функций. Причём не того кода, который известен при запуске программы, а который определяется только из ввода пользователя.
1) длина и указатель на первый элемент (C-style).
2) указатель на первый элемент массива, в котором последний элемент отмечен терминатором (C-string-style).
3) указатели на первый элемент и past-the-end (STL-style).
4) (ссылка на) весь STL-контейнер.
5) Range (Alexandresku-style).
5) - а это что за метод? не видел такого у Александреску что-то... Можно пример?
А судя по фоткам у вас неплохо оборудовано рабочее место. Неужели необходимо такое количество кофе?))
А вообще - попробуйте цикорий. Вкус примерно тот же, а вот содержание более щадящее для организма.
>Object[],
В C# такой траблы нет. Дженерики в сишарп возвращают реальный тип. никаких лишних приведений.
Такое извращение было сделано, чтобы байткод Java 5+ был 100% совместим с байткодом Java 5-
Это затратная для контейнеров O(n) операция. Глупо. Тем более с двойной затратой памяти.
В C# без затрат CPU:
Точно не скорости исполнения.
Проблемы Java такие же как и у С++. Поддержание наследственности. Толи в сишарп передал интерфейс:
и никаких тебе String... с его String[]. И теперь можно сувать любые контейнеры.
Вот чего в java действительно очень не хватает - функции как объекты первого рода. Объявление анонимного класса обычно занимает больше места, чем заключённая в его реализацию логика. Вот это реально бесит.
да, пожалуй.
мясо.
> Вот Scala - это наиболее реальный выход из проблемы
ага, и playframework
Коллекции же реализуют интерфейс Collection и являются динамическими, но их довольно много, и непонятно, какой нужен бы для varargs. Вот и выбран путь "наименьшей сложности"
А для записи не удобно? (:
А вот использовать массивы для алгоритмов, требующих расширение контейнера, очень глупо.
А почему бы и нет? Сортировка без лишнего копирования 100500 элементов? Вроде не плохо. А в varargs функцию вполне могут передать массив с таким кол-вом элементов. Например, тарас так сделает.
Массив передаётся в придачу, кроме просто множества параметров. А можно и другие виды контейнеров.
{
...
};
> Ох да, я пишу в объектно ориентированном стиле и возвращаю много объектов из функций. В чем проблема то? Когда это стало проблемой? Это регулярная операция уже оптимизирована по самое не могу. RVO, NRVO, RValueReference и много прочего.
А я не про это. А про то, что вызов такой хитрожопой функции (которая на самом деле хрен знает что) будет куда медленнее, чем вызов настоящей функции.
http://forum.pascal.net.ru/index.php?showtopic=28513
А у вас нет результатов бенчмарков замыканий для менее специфичных языков? Java-аналоги замыканий ничем не отличаются от остальных объектов, только несколько ограничены в возможностях и требуют громоздких конструкций.
> MemoryOverflowAtCompileTimeWhenCompileNe wFunctor
Ну и что?
> Это будет медленно при первом вызове.
Да.
> Да и реализация не тривиальная.
Вшить в программу компилятор и байт-коды функций.
> Запись в сегмент кода - сброс всего кеша кода.
Ничего.
> Если уж у вас так много идей по оптимизации кода - напишите наконец свой компилятор.
У меня нет ресурсов для этого.
Мозг есть, руки есть, компьютер есть. Или я ошибся по всем 3м пунктам?
Ежегодно тысячи дипломников пишут свои компиляторы или интерпретаторы. Последуй их дорогой и обгони. Сделай сам дельфи своей мечты.
Знаю сложно, но те кто не тратят время и не плачутся на говнокоде о недостатках всех компиляторов мира и мира в целом - добиваются успеха. Тем более тебе любые велосипеды по колено, если вспомнить твои недавние заявления.
Кроме мозга, рук и компьютера, нужно время (3 месяца) и скорость, чтобы в это время уложиться. Если не уложиться - интерес пропадает, проект забрасывается.
Я не уложусь, даже если воспользуюсь помощью gcc.
Если новый код должен ввести пользователь в процессе работы программы, и этот код может быть сколь угодно сложным (не просто пара арифметических операций над парой чисел, что можно реализовать с помощью пары чекбоксов и т. п,), то самый быстрый и простой способ: пусть вводит код текстом. А этот текст передаём компилятору. Тот же Tiny C Compiler можно использовать. А потом, после компиляции, можно использовать полученную программу. Работать она будет быстро, без всяких издержек на виртуальные вызовы и т. п.
Я ВСЕХ ВАС ТРОЛЛЮ У ВАС У ВСЕХ БАТТХЁРТ
Минусовать не я первый начал.
И вообще, тут серьёзные вещи обсуждают, а ты херню мелешь, если тебе тема неинтересна, то чего пришёл тогда.
А, ещё смайлики и слово "баттхёрт". Полный набор.
и уж точно не я. я своих собеседников никогда не минусую. То, что у него другая точка зрения не означает, что он не прав.
> тут серьёзные вещи обсуждают
Пока я никаких серьёзных вещей не увидел. Ты пишешь про замыкания и частичные применения, а в том же Haskell это настолько обычная и часто используемая вещь, что никто даже не задумывается о том, что втыкать в каждый бинарник компилятор.
Вот когда у тебя будет рабочий прототип с бенчмарками, доказывающими, что твои замыкания круче всего того, что уже есть - тогда можно говорить о какой-то серьёзности. Пока всё на уровне [code=blue]http://govnokod.ru/7746[/color]
Я говорю про их реализацию через компиляцию по ходу выполнения, а не через тормозную эмуляцию. Только не надо говорить, что это якобы не надо. Надо.
Ну и ещё я говорю про компиляцию на ходу не через текст (это кривизна), а через замыкания и частичное применение. Одно с другим соединить, короче.
> Вот когда у тебя будет рабочий прототип с бенчмарками, доказывающими, что твои замыкания круче всего того, что уже есть - тогда можно говорить о какой-то серьёзности.
Это уже чистый троллинг. А в спорах об автомобилях ты тоже говоришь что-то типа "собери свой автомобиль, а потом спорь"?
> и уж точно не я. я своих собеседников никогда не минусую
А, ну извини тогда.
Нет, друг мой, всё не так. Просто я вижу, что дальше разговоров дело не зайдёт. Поэтому относиться к этому серьёзно очень сложно (как вообще ко всему, что происходит на ГК).
Линус вон не ходил по форумам и не троллил, а сидел и ваял свою ось, потому что существующие его не устраивали. В итоге он на коне.
Это кривизна. Надо, чтобы передавался не текст, а логические структуры.
А для передачи текста надо, чтобы программа помнила имена своих переменных и функций.
Синтаксис определенения замыканий и частичного применения больше подходит.
Глюков нет. Там динамическая типизация.
Значит глюки переходят на этап выполнения
Та функция, что ты декомпозируешь:
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, что не всех устроит.
Перед тем, как продать его Майкрософту?
Интересно, каким парсером пользуются сейчас создатели языка C# для оного в современном виде?
PEG есть только для немерле?
1 ый вопрос: Сами немерловцы написали и никакого отношения к майкрософтовскому сишарпу нет.
3 ий вопрос - глупый.
Число подъемов в одном марше между площадками (за исключением криволинейных лестниц) должно быть не менее 3 и не более 16. В одномаршевых лестницах, а также в одном марше двух- и трехмаршевых лестниц в пределах первого этажа допускается не более 18 подъемов.
СНиП 2.08.02-89. Общественные здания и сооружения.
А как в жилых домах, не знаю. Надо гуглить.
Кстати, мне кажется, что оценки типа "+1" не очень информативны. Лучше бы выводить более подробную информацию типа "+5 -4" типа пятеро за, четверо против. А то не всегда понятно - всем похер или мир разделился пополам :)
сраказм
Тех, кто минусует его комментарии больше и плотнее остальных.
А также однокакашников - тех, кто плюсует.
Еще ввести фрэнд ленту, добавить награждение за самое большое количество однокакашников и награждать победителей подписью с рисунком понега до следующего подсчета результатов (например, проводить подсчет каждую неделю)
И запилить блять чатик
Я воспринимаю это как моё личное отношение к сообщению, но не к автору. Если автор мудак, и получает много и часто - это только его проблемы.
К счастью, тут "карма" ни на что не влияет.
если вы не заметили, я не предлагаю сделать врагом каждого, кто минусанул, а только тех, количество минусов которых перешло через какой-либо разумно подобранный порог.
Херня это все, конечно, но ведь спарта жеж =0
Как ни крути, а общение на этом ресурсе является главной составляющей...
Мы предлагаем: Достойная зарплата без задержек, справка 2-НДФЛ, карьерный рост, бесплатное обучение,
свободный график, страховые взносы в Пенсионный фонд, официальный договор (по желанию).
График работы, Вы определяете самостоятельно, по своим возможностям.
Ваш возраст и образование значения не имеют.
Обязательные условия: наличие компьютера и интернета.
Ваши действия:
1. На сайте ( www.off-rabota.tk ) скачайте и установите приложение.
2. Ознакомьтесь с содержимым.
3. Пройдите несложную регистрацию.
4. Обязательно, пройдите курсы обучения. (Бесплатно)
5. Начинайте зарабатывать!
Зарплату мы перечисляем только на банковскую карту любой платёжной системы.
(Для работы советуем оформить отдельную карту)
ВНИМАНИЕ! Весь процесс регистрации, обучения совершенно бесплатны. Не попадитесь в руки мошенников!