Здравствуйте, alex_public, Вы писали: _>О, т.е. мы можем взять экземпляр любого класса и разместить его в стеке или как?
Зачем любого? Есть типы, которые хорошо работают с value-семантикой — например, TimeSpan, DateTime, Decimal.
Вот их можно запросто разместить на стеке.
А вот как, и, главное, зачем размещать на стеке объекты типа WebRequest я, простите, не понимаю.
_>Только при условие бесконечной памяти. Я уже кинул Владу ссылку на полезную статью на эту тему. Ну повторю на всякий случай: http://habrahabr.ru/post/188580/.
Не бесконечной, а достаточно большой.
Понятно, что GС даёт оверхед. Но даже в случае предельно ограниченной памяти, хороший GC даёт всего 70% потерь по сравнению с ручным менеджментом.
При двукратном превышении — отставание всего 17%. Начиная с 2.5-кратного превышения, перформанс GC и ручного управления становятся неразличимы.
На минуточку напомню, что мы говорим не о производительности приложения, а о затратах только на memory management. Т.е. если приложение хотя бы половину времени тратит на полезную работу, то разница между подходами к управлению памятью сокращается ещё вдвое.
И это — в обмен на гарантии type safety!
Для очень широкого класса задач это более чем приемлемая цена.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
_>>А зачем мне так писать? S>Затем, что у вас в сигнатуре — A*.
Голые указатели в современном C++? Какая ересь. Тогда уж unique_ptr<A> будет...
S>Ок, я был недостаточно убедителен. S>Отлично — вы пишете S>
S>auto b = someOtherCoolFunction(a);
S>
S>Как будет работать move constructor? Я так понимаю, что без inlining-а у компилятора маны не хватит на замену copy на move.
Во многих случаях хватит. ) Но если нет, то можно ему подсказать, написав auto b = someOtherCoolFunction(move(a));.
S>А если вы обнаружите, что стоимость копии a здесь чрезмерна, то попробуете передавать его по ссылке. S>Но у вас нет никакой гарантии на то, что эту ссылку someOtherCoolFunction не прикопает ещё где-то — например, не передаст её в другой поток. S>То есть мы опять возвращаемся к ручному управлению временем жизни и надежде на то, что "авось не стрельнет".
Это всё в прошлом. )
S>Расскажите вкратце, как move semantics определяет, где её можно использовать, а где — нельзя.
Применяется ко всем временным объектам, т.е. грубо говоря таким, которые дальше однозначно не используются (соответственно автоматически подходят все return'ы, цепочки вычислений и т.п.). Плюс можно самому указать (см. выше).
S>Зависит от задачи. Понятно, что если у вас адски ограниченный memory footprint, то GC — не ваше всё.
Это не единственная проблема. Остановки мира тоже совсем не радуют на некоторых задачах. )
Re[56]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, alex_public, Вы писали:
_>Во многих случаях хватит. ) Но если нет, то можно ему подсказать, написав auto b = someOtherCoolFunction(move(a));.
А что скажет компилятор на auto c = yetAnotherCoolFunction(a); парой строчек ниже?
_>Применяется ко всем временным объектам, т.е. грубо говоря таким, которые дальше однозначно не используются (соответственно автоматически подходят все return'ы, цепочки вычислений и т.п.).
Ну, то есть тот же самый escape analysis. _>Плюс можно самому указать (см. выше).
Ага, вот это — основное отличие от EA. _>Это не единственная проблема. Остановки мира тоже совсем не радуют на некоторых задачах. )
Stop the world коллекторов в природе осталось мало.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[49]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Sinclair, Вы писали:
S>Зачем любого? Есть типы, которые хорошо работают с value-семантикой — например, TimeSpan, DateTime, Decimal. S>Вот их можно запросто разместить на стеке. S>А вот как, и, главное, зачем размещать на стеке объекты типа WebRequest я, простите, не понимаю.
Ну вообще то работа со стеком заметно быстрее. Так что как раз нужны причины для не размещения на стеке.
S>Не бесконечной, а достаточно большой. S>Понятно, что GС даёт оверхед. Но даже в случае предельно ограниченной памяти, хороший GC даёт всего 70% потерь по сравнению с ручным менеджментом. S>При двукратном превышении — отставание всего 17%. Начиная с 2.5-кратного превышения, перформанс GC и ручного управления становятся неразличимы. S>На минуточку напомню, что мы говорим не о производительности приложения, а о затратах только на memory management. Т.е. если приложение хотя бы половину времени тратит на полезную работу, то разница между подходами к управлению памятью сокращается ещё вдвое.
Сомнительные цифры, т.к. не указана реализация ручного управления — может там всё в том же самом стеке лежит?) Это больше похоже на изменение производительности GC относительно своего же идеального варианта. Вот в такое мне вполне верится...
S>И это — в обмен на гарантии type safety! S>Для очень широкого класса задач это более чем приемлемая цена.
Насчёт последней фразы я конечно же согласен. ) К примеру я сам с удовольствием использую Python (а там вообще всё мрачно в этом смысле) и нисколько не напрягаюсь из-за его GC. )
Re[50]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, alex_public, Вы писали: _>Ну вообще то работа со стеком заметно быстрее. _>Так что как раз нужны причины для не размещения на стеке.
Даже если вы сможете запихать WebRequest, у которого все члены — сплошная динамика, на стек, то выигрыш вы не сможете заметить и в микроскоп.
Банальная валидация URL на корректность уже сожрёт на порядок больше, чем инкремент heap pointer. Это я уже не говорю про собственно раундтрип на сервер — мы же webRequest не ради стека создаём.
_>Сомнительные цифры, т.к. не указана реализация ручного управления — может там всё в том же самом стеке лежит?) Это больше похоже на изменение производительности GC относительно своего же идеального варианта. Вот в такое мне вполне верится...
Ручное управление — через malloc и free. Читайте не пересказ для чайников, а ту самую статью, ссылка на которую лежит рядом со слайдом (2006 года, кстати. Т.е. в 2014 можно бы и перемерить результаты).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[50]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Sinclair, Вы писали:
S>>Зачем любого? Есть типы, которые хорошо работают с value-семантикой — например, TimeSpan, DateTime, Decimal. S>>Вот их можно запросто разместить на стеке. S>>А вот как, и, главное, зачем размещать на стеке объекты типа WebRequest я, простите, не понимаю.
_>Ну вообще то работа со стеком заметно быстрее. Так что как раз нужны причины для не размещения на стеке.
Причина очень простая — время жизни объекта более чем вызов ф-ции/метода. Т.е. выигрыш может быть заметен только для локальных переменных.
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 58>>
♠♠♥♠♠♦♥
Re[57]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Sinclair, Вы писали:
S>А что скажет компилятор на auto c = yetAnotherCoolFunction(a); парой строчек ниже?
Ничего не скажет. Просто в yetAnotherCoolFunction пойдёт пустой объект.
_>>Применяется ко всем временным объектам, т.е. грубо говоря таким, которые дальше однозначно не используются (соответственно автоматически подходят все return'ы, цепочки вычислений и т.п.). S>Ну, то есть тот же самый escape analysis.
Нуу не совсем. Всё же это не оптимизация, реализация которой может меняться в каждой версии, а чётко зафиксированный стандарт языка.
_>>Плюс можно самому указать (см. выше). S>Ага, вот это — основное отличие от EA.
На самом деле в большинстве случаев автоматики хватает, а это для какой-то специальной оптимизации к примеру в замыканиях и т.п. Они же с приходом полиморфных лямбд стали совсем удобными. Можно даже такой http://coliru.stacked-crooked.com/a/ce0de866fa9e05bc беспредел творить. )))
Re[51]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Sinclair, Вы писали:
S>Даже если вы сможете запихать WebRequest, у которого все члены — сплошная динамика, на стек, то выигрыш вы не сможете заметить и в микроскоп. S>Банальная валидация URL на корректность уже сожрёт на порядок больше, чем инкремент heap pointer. Это я уже не говорю про собственно раундтрип на сервер — мы же webRequest не ради стека создаём.
Если запихивание требует каких-то усилий, то естественно в этом нет смысла. А если это как раз стандартная техника работы в языке, то почему бы и нет? )
Re[47]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Sinclair, Вы писали:
S>Объекты фиксированного размера со стековым временем жизни в дотнете делаются на структурах и работают с той же скоростью, что и в С/С++. S>А объекты динамического размера (строки, массивы) при детерминистической финализации таки проигрывают практически любому современному GC.
А в чем пробелема поместить обьект диманического размера в стек? Как-нить так:
void f(uint64_t value)
{
int n = __builtin_popcountl(value);
uint64_t tmp[n];
for (int i=0; i<n; ++n) {
tmp[i] = value & (-value);
value ^= tmp[i];
}
/* Process tmp */
/* ........... */
}
Re[58]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, alex_public, Вы писали:
S>>А что скажет компилятор на auto c = yetAnotherCoolFunction(a); парой строчек ниже?
_>Ничего не скажет. Просто в yetAnotherCoolFunction пойдёт пустой объект.
Отличная грабля. И это в то время, когда передовики производства совершенствуют средства обнаружения lack of definite assignment, у нас С++ неспособен отрепортить definite lack of assignment?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[48]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Mystic, Вы писали:
M>А в чем пробелема поместить обьект диманического размера в стек?
А какого размера у вас stack? Если я попробую поместить в стек 36мегабайтный битмэп, он не треснет?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[49]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Sinclair, Вы писали:
M>>А в чем пробелема поместить обьект диманического размера в стек? S>А какого размера у вас stack? Если я попробую поместить в стек 36мегабайтный битмэп, он не треснет?
Поэтому у программиста C есть вьібор, где и как помещать.
Re[60]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Sinclair, Вы писали:
EP>>Я думаю это дело даже можно частично автоматизировать — если после копии ref-counted куда-то, он больше не использовался — то достаточно move'а. S>О, ещё немного — и вы изобретёте escape analysis.
Во-первых, совершенно не в тему — мы говорим про минимизацию ++/--ref_count, а не конвертацию аллокаций в куче в аллокации на стэке.
Во-вторых, если уже говорить про escape analysis, то основной benefit который он даёт — в C++ это поведение по умолчанию
EP>>>>Поделись соображениями. С одной стороны у нас редкие wait-free inc/dec, WH>>>Про то, что они редкие это исключительно твоя спекуляция. EP>>Причём достаточно чтобы счётчик прошёл только следующую последовательность состояний: "1, 2, 1, 0". А вот передёргивать при переходе, например, от состояния "получаем" к "отправляем" — нет никакой необходимости, достаточно move — так как эстафета передаётся. S>И как компилятор гарантирует нам отсутствие обращений к источнику после move?
Там где он может гарантировать — он сам ставит move. А там где нет — его ставит пользователь.
Более того, использовать объект после того как из него что-то move'нули вполне возможно.
EP>>Раз он точный, то память уплотнить (и обновить указатели) не проблема, но ограничения определённые есть. При решении каких-то затейливых задач с жёсткими циклами — вполне себе вариант. S>Точный GC в реальный C++ воткнуть не удастся. Потому что в нём 99% библиотек написаны в стиле "если сейчас луна в ущербе, то lParam — это указатель на cтруктуру; а если зима — то это идентификатор ресурса. Тип структуры определяется полем length".
Во-первых, ты явно путаешь C++ и C.
Во-вторых, речь шла про какие-то специфические задачи, для которых без GC ну ни как. Я говорю о том, что для таких задач можно использовать точный GC в виде отдельной кучи (и привёл пример такого GC), а не про точный GC который будет работать для всех сторонних библиотек автоматом.
EP>>Грубо говорят если из-за бага в алгоритме он вышел за пределы диапазона, но кинул исключение — работу свою он не выполнил, постусловий не достиг, перевёл программу в неопределённое состояние. S>В том то и дело, что программу он перевёл в определённое состояние.
Каким образом? Весь вызывающий код зависел от достижения постусловий данным алгоритмом, так как он честно выполнил все предусловия. Но этого не случилось из-за бага — получаем неопределённое состояние.
S>Это гораздо, гораздо лучше неопределённого состояния, которым так гордятся программисты C++.
Пруф.
Re[51]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, DarthSidius, Вы писали:
_>>Ну вообще то работа со стеком заметно быстрее. Так что как раз нужны причины для не размещения на стеке. DS>Причина очень простая — время жизни объекта более чем вызов ф-ции/метода. Т.е. выигрыш может быть заметен только для локальных переменных.
move semantics
Re[53]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Sinclair, Вы писали:
_>>О да, написать "A a;" это конечно же намного сложнее, чем написать "A a=new A;". ) S>Вы мне лучше расскажите, что будет, если я потом напишу S>
error: address of stack memory associated with local variable 'a' returned
S>Вот только в дотнете для них же имеем ровно ту же реализацию. S>А как только вы выйдете за их пределы и начнёте работать хотя бы со строками, вот тут и начнётся веселуха — либо беспричинные копирования со штрафом O(N), либо шансы нарваться на обращение к уничтоженному объекту, либо рефкаунты. А escape analysis позволяет программисту не думать о том, какие строки у него временные, а какие — надолго.
#include <string>
using namespace std;
string test()
{
string x = "abc";
return x;
}
Не тут, ни "штрафа O(N)", ни refcount
Re[57]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, Sinclair, Вы писали:
S>А как только вы выйдете за их пределы и начнёте работать хотя бы со строками, вот тут и начнётся веселуха — либо беспричинные копирования со штрафом O(N), либо шансы нарваться на обращение к уничтоженному объекту, либо рефкаунты. А escape analysis позволяет программисту не думать о том, какие строки у него временные, а какие — надолго.
Вообще говоря, тут мысль достаточно простая: там где в GC языках ставят "new", в 95%-99% случаях на C++ не будет никакого ref-counting и подобного, и это default style, причём это не только для памяти, а для всех ресурсов (с которыми в C# уже начинаются проблемы, которые не решаются полностью using-костылями).
То есть то, что себе фантазируют эвагелисты GC — "О, вот тут ставлю ещё один new, GC — хороший, escape analysis — хороший. А вот на C++ была бы обязательно возня со smart-pointers, бррр." — не более чем фантазия или впитанные рекламные мантры
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, alex_public, Вы писали:
S>>>А что скажет компилятор на auto c = yetAnotherCoolFunction(a); парой строчек ниже?
_>>Ничего не скажет. Просто в yetAnotherCoolFunction пойдёт пустой объект. S>Отличная грабля. И это в то время, когда передовики производства совершенствуют средства обнаружения lack of definite assignment, у нас С++ неспособен отрепортить definite lack of assignment?
Вообще-то там явно руками был написан std::move(a). Куда уж definitee — ты его сам руками написал.
Здравствуйте, alex_public, Вы писали:
VD>>Есть аналог на computation expressions. Он чутка медленнее, но сильно гибче. Есть еще макры для многопоточности, но я их не использовал.
_>Я правильно понял, что C# код с await/async в Nemerle сейчас работать не будет?
Все будет работать.
Упрощенно можно сказать, что async/await — это сахар над
public Task<TResult> ContinueWith<TResult>(
Func<Task, TResult> continuationFunction
)
А работу с тасками через продолжения никто не отменял.
type TaskBuilder(?continuationOptions, ?scheduler, ?cancellationToken) =
А на ComputationExpressions автоматически без лишних телодвижений.
_>А как тогда реализована работа с IOCP?
IOCP из дотнета не видны. Есть Task<T> представляющий асинхронную операцию, а как она внутри устроена информации нет, да и способов узнать вроде тоже.
Re[63]: Nemerle через 5 лет - выстрелит или скончается?
Здравствуйте, alex_public, Вы писали:
_>Если руководствоваться правилом "и так работает", то в общем то и Nemerle вообще не нужен, т.к. C# вообще то тоже вполне "и так работает".
Работает и, вопряки твоему высокомерному к нему отношению, работает не плохо.
Но, как ты верно заметили, МП в нем нет и расширяемости тоже. Еще ПМ нет, АлгТД и ряда удобных фичь немерла.
Собственно, одна из причин отсутствия масового причтия немерла среди шарп–программистов, то что шарп худо–бедно но развиваться. Линк — прекрасен. Лямбды тоже. Дженерики тоже не плохи, хотя и с проблемами.
_>А вот если всё же пытаться что-то улучшить, то можно увидеть что IEnumerable является очень бледной тенью Range из D.
Если ты попытаешься разобраться, узнаешь, что IEnumerable не догма ни в линках, ни в foreach. И то и другое спроектированно на базе паттернов.
Так что можно и производительность улучшить за счет перегрузок, и от использования интерфейсов избавиться.
Создание альтернативной экосистемы коллекций (например, в стиле stl) поломает совместимость, а большого толку не даст.
_>Причём как раз Nemerle (ну судя по тому, что ты о нём говоришь — я то его не изучал пока) мог бы легко поправить это.
Все и так не плохо. Хотя идея не лишина смысла. Можешь заняться. Будет еще один плюс и ещё одна альтернатива. Лично меня более–менее устраивает дотнетный подход и есть куча других задач.
_>Точно вот прямо все сделали? )
Все примерно как в плюсах. Все сделать нельзя. Сделано то что было востребованно теми кто использовал язык. Ну а частные проблемы можно решать создавая частные макро–либы. Если получится универсальное решение его можно предложить в стандартную макро–либу.
_>Гмм... И кто это только что говорил о самомнение, снисходительном отношение и т.п? )))
Я вижу, что ты и шарпе то не глубоко копал, а уж фичи из F#–я ты наверняка не не знаешь. В прочем, буду рад ошибиться.
Оператор структурного присвоения вообще штука еникальная. Делали аналог парповского инициализатора списков, а получилась вындервафля.
_>Я правильно понял, что C# код с await/async в Nemerle сейчас работать не будет?
Да. Хотя можно на те же компютейшоны транслировать. Но это поддержку шарпа нужно расширять.
_>А как тогда реализована работа с IOCP?
Что имеется в виду под этим сокращением? Completion Port винды? Если — да, то в дотнетных либах никаких проблем с ассинхроннвюым IO нет. Везде есть соответствующие перегрузки. Ну, а компьютейшоны отлично подходят для их "ввпрямления".
_>Это не разговор. Нужна целевая ниша.
Не нужна. Достаточно знать ограничения платформы.
_>Я вполне понимаю где выгодно применять Java/C#, где выгодно C++, а где Python и т.п. Так вот для Nemerle у меня нет такого же понимания. Потому как базируясь на платформе ориентированной на снижение цены разработки, он наоборот требует повышенной квалификации от программиста.
Все высокоуровневые языки ориентированы на снижение цены разработки. Посто есть и другие критерии. Скажем дотнет вряд ли приемлем для разработки для iOS или для драйверов. Питон не пригоден для требовательных к производительности алгоритмов, плюсы для задачи где надежность стоит сильно выше производительности.
Скажем если по прочим критериям задаче можно решить на Питоне, плюсах или Немерле, то я выберу Немерле именно из–за того, что на нам получится реализовать проект проще и дешевле.
_>Ты периодически как-то извращённо понимаешь мои слова. Когда я говорю о профессиональных инструментах, то совсем не подразумеваю, что использование этого инструмента сделает человека профессионалом, как ты почему-то подумал. Откуда такая странная мысль? Я под этим подразумеваю, что для использования этого инструмента требуется повышенный уровень знаний, т.е. что имеется большой порог вхождения. И это как бы минус в условиях современного бизнеса, который должен обязательно чем-то компенсироваться.
Это и есть твое надменное отношение. Ты ставишь знак равенства между специализацией (знанием граблей и паттернов позволяющих на них не наступать) и проффесианолизмом.
Если бы ты сказал "внимательности", "ответственности" и т.п. я бы не имел ничего против. Но делить людей на профессионалов и нет только на основании используемого языка — это просто глупость. Если я писал на плюсах (весьма успешно) и перешел на шара, я вдруг стал не профессиональным ламером? Гы–гы.
_>К примеру я помнится видел какие-то исследования (по студентам кажется смотрели), что саму концепцию МП способны нормально осознать и применять только часть программистов.
И что? Ну вот использует некоторый шарпщик T4.
Чем он от "проффесионала" лабающий код на плюсах без МП отличается?
_>Про плагины я давно видел. Но я так и не понял, имеется ли какое-то чёткое формальное разделение nemerle кода с макросами и без?
Макросы — это (грубо говоря) точка входа в программе. Она вызывает некий код который трансформирует код программы.
У макр есть свой спец синтаксис.
Но рассказывать об это долго. Особенно с телефона.
Почему бы не прочесть вводную статейку да не попробывать самому?
_>Насчёт костылей тут очень тонкий вопрос...
Вопрос очень прост. В дотнете есть функциональный тип (делегаты) , а в прюсах нет. Буст лечил эту недоработку, пока фанаты С++ обясняют почему эта фича не нужна...
_>...С ходу кроме Spirit'a вспоминаются Boost.Unit, Boost.Xpressive, Boost.MSM. Это из тех, что я сам трогал, а это естественно далеко не все.
Ну, вот ровно для этих задач и есть решения на макросах. Плюс еще эндцать задачек. Но контейнеры удовлетворяют дотнетовские. А если чего–то нет, то можно создать нужную реализацию без макросов. Кстати, в std: :vector я тоже МП не припоминаю. .
_>Ну а вообще для программирование на Nemerle я бы поискал образцы скорее в стандартной библиотеке D, а не в Boost'e. Всё же в C++ МП слабенькое...
ОК. И что там?
Кстати, для ди инфраструктура всетаки есть или ее нет?
_>А, понял. Ну так напомню, что Spirit — это не только парсер, но и генератор (ну и лексер ещё там есть). Хотя если этот твой код умеет скачивать и проверять при генерации xml схему, то такого конечно даже близко нет. А если без учёта схемы, то вроде как простая вещь.
Схему не умеет, но научить это делать элементарно. Просто берем схему и проверяем через имеющицся АПИ. Это же не шаблоны. Макры могут хоть в интернет сходить, хоть в базу данных залезть.
_>Я правильно понял, что ты считаешь, что с помощью МП улучшать в контейнерах .net'a нечего? )
В этом нет необходимости.
А в каких контейнерах stl используется МП? И зачем?
_>Там счётчик и кое-какие флаги хранятся в самом указатели (на 64-ёх битных процессорах естественно).
И что? Это спосает отзацикливаний, фрагментации памяти и необходимости тратить время на подсчет ссылок и очистку памяти при нулевом их числе?
_>Готов принять, если и ты готов. )
Sing Sharp (or Sing#) is a superset of Spec Sharp. Microsoft Research developed Spec#, and later extended it into Sing# in order to develop the Singularity operating system. Sing# augments the capabilities of Spec# with support for channels and low-level programming language constructs, which are necessary for implementing system software.
_>Так что там про ляля? )
Ну, так потрудись найти список этих low-level programming language constructs. Может я чего не знаю.
VD>>И чем этот рекламный булшит противоречит процитированному мной? Мы уже выяснили, что systems означает "наличие указателей" гы–гы.
_>Мдааа. )
Что "мда"? Это твои слова? Если ты с собой не согласент, то дай другое определение того, что в языке должно быть, чтобы он стал "сиссстемным".
_>Это программно-аппаратный комплекс, состоящий из нескольких взаимодействующих модулей. )
Яснее сильно не стало.
_>Да, местами реалтайм (это в микроконтроллерах), а местами просто быстрый код (это в "кодеках").
Ну вот тут спорить не буду. Это задачи для С/С++. Но вы же не только их на плюсах решаете?
VD>>Гуй на С++ пишете?
_>Да)
Ну вот это совсем не по делу применение, если, конечно там все не настолько приметивно, что по фиг на чем писать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.