Ещё раз о насильниках

Ivan8209

http://www.faqs.org/docs/artu/why_not_c.html
---
"Аллах не ведёт людей неверных."

Olenenok

ага, вчера кодил на паскале. круто, очень быстро, менее чем за час, написал замену map <string, list<string>>

vook

А что в Паскале есть GC? А то иначе не понятно нафиг ты это написал.

Olenenok

кхмдагбухгдрапроакупк
понадобилась ассоциировать слово со списком его возможных замен (key, [subs1, subs2, .., subsN])

Landstreicher

Все изложенное ниже является субъективным IMHO.
Покодив пару-тройку лет на C++, пришел к выводу, что программы надо писать так:
1. Разбивать программу на 2 части: низкоуровневую и высокоуровневую. К низкоуровневой могут относиться, например перемножения матриц, FFT, (де)кодирование DivX, работа с ОС итп. К высокому уровню, наоборот, относится "логика" программы, GUI.
2. Низкий уровень пишется на C или ассемблере. Подчеркну — именно C, не C++.
3. Высокий уровень пишется на языке высокого уровня — Lisp, ML, Haskell, Python (по вкусу). Там где производительность не главное, имеет смысл использовать языки с динамической типизацией по типу Lisp/Python.
4. Через FFI связывать две части.
Обращаю внимание, что в такой схеме используются два уровня языков — высокий и низкий. Языков среднего уровня (C++, Java, C#) в этой схеме нет. Эти языки — неудачная попытка соединить в одном языке и низкий, и высокий уровень. Эта идея в корне неверна, получающиеся при таком межродовом скрещивании языки являются генетическим уродами и не могут нормального выполнять функции ни языка низкого уровня, ни языка высокого уровня. Использовать подобные языки — только зря тратить время и нервы.

Dasar

т.е. какой-нибудь офис можно реально написать на ML?

Landstreicher

> т.е. какой-нибудь офис можно реально написать на ML?
Если его можно написать на C++, то можно и на ML.

Dasar

> Если его можно написать на C++, то можно и на ML.
плохо себе представляю как решаются на ML следующие задачи:
1. Разбиение на модули
2. Спецификация стыков
3. Командная работа
> Если его можно написать на C++, то можно и на ML.
следующее утверждение тоже верно "Если его можно написать на C++, то можно и на машине тьюринга", но практического смысла не имеет...

Ober

+1. Мы выбираем Scheme + C или Python + C

vook

Буээ. CL + C рулит.

Olenenok

не всегда это хорошо. например для окошек с++ получше. живой пример - Qt vs GTK

Ober

CL + C
Это тоже можно, да. Но как-то вот исторически не сложилось с CL...

Ober

Qt vs GTK
типа холивар, да?

Olenenok

типа холивар, да?
ну нафик, просто Qt реально лучше

Ober

просто Qt реально лучше
чем же и в каких случаях?
P.S. мне, честно говоря, почти пох, что из них использовать

Olenenok

а мне не пох.
Qt - глянул, через день уже написал то что было нужно
потом посмотрел GTK - ужоснах. особенно длина имён функций

nikita270601

Qt отстой, потому что некоторые его пишут как QT, и возникает путаница - непонятно, говорят про Qt или про QuickTime!

Landstreicher

> плохо себе представляю как решаются на ML следующие задачи:
> 1. Разбиение на модули
> 2. Спецификация стыков
> 3. Командная работа
1, 2 - прекрасно решаются. Гораздо лучше чем в C++ или Java например.
3 - это о чем? CVS или SVN?
> следующее утверждение тоже верно "Если его можно написать на C++, то можно и на машине
> тьюринга", но практического смысла не имеет...
Ошибаешься, данное утверждение не верно.

Landstreicher

> не всегда это хорошо. например для окошек с++ получше. живой пример - Qt vs GTK
Не понял, какая связь между C++ и Qt?
Неоднократно писал GUI на Python с применением Qt. Также были случаи написания GUI на Python с использованием GTK.

Ivan8209

Про 1 и 2 уже говорили, я даже приводил пример.
---
"Неправда, что умные --- те, кто учится на чужих ошибках, а дураки --- на своих.
Никто не учится на чужих ошибках. Умные отличаются от дураков только тем, что
последние вовсе не учатся."

psihodog

Языков среднего уровня (C++, Java, C#) в этой схеме нет. Эти языки — неудачная попытка соединить в одном языке и низкий, и высокий уровень. Эта идея в корне неверна, получающиеся при таком межродовом скрещивании языки являются генетическим уродами и не могут нормального выполнять функции ни языка низкого уровня, ни языка высокого уровня.
+1
то же самое я сказал своему начальнику, когда заботал C#.

Ivan8209

CL отстой.
/path/to/your/HyperSpec/Body/06_a.htm --- это не блин.
Я лучше не буду говорить, что это.
Такие DSL приличные люди держат в дополнительных расширениях, а не в ядре.
---
"Аллах не ведёт людей неверных."

Ivan8209

> Некоторым людям неплохо было бы научиться программировать.
> Чтобы потом они не писали нонсенсов о наличии (мемори) ликов в Си++,
> его неспособности выполнять роль языка высокого уровня, и т.п.
Одна из важнейших способностей языка высокого уровня --- автоматическое управление памятью.
Плюсы с этим не справляются, хотя сборка мусора не такое уж сверхнеобычное занятие.
---
"Аллах не ведёт людей неверных."

kokoc88

Одна из важнейших способностей языка высокого уровня --- автоматическое управление памятью.
Плюсы с этим не справляются, хотя сборка мусора не такое уж сверхнеобычное занятие.
Разговор продолжим, когда и если ты узнаешь, что такое Си++ и как в нём работать с памятью.

Ivan8209

Я и так знаю, и что такое C++, и как в нём работать с памятью.
То, как предлагается работать, это отстой.
---
"Аллах не ведёт людей неверных."

kokoc88

Я и так знаю, и что такое C++, и как в нём работать с памятью.
Если бы ты это знал, не писал бы такую чушь.

Ivan8209

Да пусть это будет чушью, господи, раз тебе так нравится закатывать солнце вручную.
---
"Аллах не ведёт людей неверных."

kokoc88

закатывать солнце вручную
Вот ещё один нонсенс. Лол.

Ivan8209

Ты довёл явное выписывание распределения памяти до автоматизма? Ну-ну.
---
"Narrowness of experience leads to narrowness of imagination."

kokoc88

Ты довёл явное выписывание распределения памяти до автоматизма?
Выше я уже отправил тебя учить матчасть?... Кажется, да... А ты вместо этого флудишь и пишешь глупости.

Ivan8209

Я прекрасно знаю матчасть.
Даже лучше, чем ты.
Если ты довёл своё ручное управление памятью до автоматизма, оно не перестало быть ручным.
Можно, подобно каким-нибудь зулусам, прекрасно обходиться фитильным ружьём,
можно научиться заряжать его в темноте и за спиной, только это всё равно останется
_ручной_ работой.
---
"Narrowness of experience leads to narrowness of imagination."

kokoc88

Я прекрасно знаю матчасть.
Даже лучше, чем ты.
В недалёком прошлом практика показала совсем другое. Ты не знаешь даже своих не насильных языков. Ты не способен на них написать программу, которая бы правильно работала. О каком удобстве в этих языках может идти речь, если их приверженцы просто не умеют программировать?
своё ручное управление памятью до автоматизма

Опять 25. Учи матчасть.

Ivan8209

> В недалёком прошлом практика показала совсем другое.
В недалёком прошлом практика показала не это.
> Ты не знаешь даже своих не насильных языков.
> Ты не способен на них написать программу, которая бы правильно работала.
Мои программы работают правильно.
Если у тебя идеалистическое понимание правильности, это твои личные трудности.
> О каком удобстве в этих языках может идти речь, если их приверженцы просто не умеют программировать?
Если для тебя "программировать" означает "программировать на плюсах", это твои личные трудности.
---
"Аллах не ведёт людей неверных."

garikus

А что в Паскале есть GC?
В новом есть

kokoc88

В недалёком прошлом практика показала именно это.

Ну да, именно это она и показала. Ты не смог сразу написать простейшую программу на SCHEMA. В ней нашли баги. Ты её исправил. В ней опять нашли баги. В итоге ты так ничего и не дописал. (Для справки, я ради интереса-таки дописал. Ага, на SCHEMA.)
Мои программы работают правильно.
Если у тебя идеалистическое понимание правильности, это твои личные трудности.
У меня понимание правильности вполне себе простое. Программа должна выдавать требуемый результат на некоторых входных данных. Ты с этой задачей не справился.
Если для тебя "программировать" означает "программировать на плюсах", это твои личные трудности.

Нет, для меня умение программировать означает умение решать задачи на любом языке. Желательно без дурацких ошибок, которые ты делаешь пачками. И вовсе не значит умение написать "man blabla", "info lalalal", вы все лохи, вы все насильники.
PS Матчасть-то выучил? Вижу, что перестал писать про "ручные" решения с памятью на Си++. Или просто не смог въехать?

Ivan8209

> У меня понимание правильности вполне себе простое.
> Программа должна выдавать требуемый результат на некоторых входных данных.
Ага, то есть ты всё-таки оставил себе отходной путь, про "некоторые" написал.
> Ты с этой задачей не справился.
Тогда ты не просто лжёшь, а нагло лжёшь.
"Баги" ты находил вне "некоторых" входных данных, на которых программа работала сразу и успешно.
> Нет, для меня умение программировать означает умение решать задачи на любом языке.
Ну-ну, что-то незаметно, чтобы ты умел "на любом языке".
Хотя бы на английском-программистском научился бы писать.
Кроме того, я не помню, чтобы ты в том недавнем случае вообще предоставил решение.
Наверное, это от большого умения программировать.
---
"Аллах не ведёт людей неверных."

Ivan8209

> Вижу, что перестал писать про "ручные" решения с памятью на Си++.
И не переставал.
Перестану, когда сборщик мусора в вашем языке появится.
---
"Аллах не ведёт людей неверных."

kokoc88

И не переставал.
Перестану, когда сборщик мусора в вашем языке появится.
Понятно. Ну тогда вывод один: матчасть ты не знаешь. Прежде чем наезжать на какой-то язык, следует повнимательнее изучить его возможности и достоинства. А потом уже переходить к недостаткам.

Ivan8209

> при использовании GC часто забывают где-то ссылку на объект.
В этом смысл сб. м.
> Например, приходится нагружать код finally, в которых освобождаются ресурсы.
То есть делать всё это _руками_.
> Причём это надо делать весьма тщательно и аккуратно.
Вот-вот.
Всё это говорит лишь о том, что ты ни разу не использовал приличный сборщик.
> Плюс ко всему, при использовании GC забывают, что у объекта нет чёткого времени завершения.
В этом смысл сборки мусора.
> И что ресурсы надо освободить вручную.
И это говорит о том, что в твоих сях нет приличного сборщика.
---
"Аллах не ведёт людей неверных."

kokoc88

Всё это говорит лишь о том, что ты ни разу не использовал приличный сборщик.
Всё это говорит о том, что ты не удосужился прочитать мои слова. Никакой приличный сборщик не спасёт тебя от случайно сохраненной ссылки на объект. Просто потому, что он никогда не узнает, что эта ссылка - утечка, и никогда больше не будет использоваться.
И это говорит о том, что в твоих сях нет приличного сборщика.

Нет, это говорит о том, что тебе надо продолжать учить матчасть.

Ivan8209

> Никакой приличный сборщик не спасёт тебя от случайно сохраненной ссылки на объект.
> Просто потому, что он никогда не узнает, что эта ссылка - утечка, и никогда больше не будет использоваться.
_Не_бывает_ случайно сохранённых ссылок. Если ты беспамятен, то это твои личные трудности.
Если ты написал "a = ref b", это означает, что ты сохранил ссылку.
Использование ссылок начинается в случаях крайней необходимости,
потому что почти всё можно сделать без них, причём ничего не теряя.
---
"Аллах не ведёт людей неверных."

kokoc88

_Не_бывает_ случайно сохранённых ссылок. Если ты беспамятен, то это твои личные трудности.
Если ты написал "a = ref b", это означает, что ты сохранил ссылку.
Ну тогда чего ты тут мне втираешь-то? Ничем GC не помогает, утечки остались. И это намного сильнее выражено в языках с GC, чем в том же Си++. Просто потому, что во втором сделать такую ошибку - надо не просто что-то забыть, а ещё и совершенно неправильно писать код. Так что два тебе за матчасть, иди учи дальше.

Ivan8209

> Ничем GC не помогает, утечки остались.
Только если ты намеренно их сделаешь.
> И это намного сильнее выражено в языках с GC, чем в том же Си++.
> Просто потому, что во втором сделать такую ошибку - надо не просто что-то забыть,
> а ещё и совершенно неправильно писать код.
Ты первым вспомнил про ссылки не просто так, просто в сях без ссылок не обойтись,
а в высокоуровневых языках они, если вообще есть, являются средством низкоуровневым.
Для усиленной оптимизации и других хардкорных задач.
Кстати, да будет тебе известно, что даже если ты сделаешь ошибку, в лиспах объект,
на который нет ссылок, соберут точно. Это неотвратимо и неизбежно.
Вернее, этого можно избежать только если программа закончит работать раньше,
чем потребуется собирать мусор, который поэтому будет сожжён вместе со всем миром.
---
"Аллах не ведёт людей неверных."

Landstreicher

В соседнем слое написали очень много, ответить на все не представляется возможным, поэтому резюмирую некоторые соображения тут.
Не стоит утверждать, что "C++ — говно" или "С++ — рулез". Такие высказывания содержат только эмоции, и не содержат никакой объективной информации.
Вместо этого я предлагаю ввести понятие "область применения языка". Это то множество задач, которые решаются на этом языке лучше (проще, быстрее, эффективнее чем на других языках.
Например, область применения языков C, ассемблер включает в себя задачу написания эффективного DivX-компрессора. Ни на каких языках высокого уровня, в том числе Lisp, ML эту задачу не удастся решить лучше. И дело тут не в том, что Lisp, ML — говно, а просто эти языки предназначены для других целей.
С другой стороны, написание оптимизатора XQuery-запросов следует делать на каком-нибудь Scheme или Haskell. Попытка писать подобное на C++ была бы полным безумием.
Не бывает плохих или хороших языков, а бывают задачи, которые попадают или не попадают в область применения какого-либо конкретного языка.
Мое утверждение можно переформулировать так: "область применения C++ — пустое множество (или близко к нему)". Тем, кто считает что это не так, — пусть опишут, какой по их мнению, она является.

kokoc88

Только если ты намеренно их сделаешь.
Что значит намерянно? Это ошибка: ты просто забываешь где-то про ссылку. В Си++ при работе с памятью таких ошибок нет.
Ты первым вспомнил про ссылки не просто так, просто в сях без ссылок не обойтись,
а в высокоуровневых языках они, если вообще есть, являются средством низкоуровневым.
Для усиленной оптимизации и других хардкорных задач.
Ты благополучно перепутал ссылки и указатели.
Кстати, да будет тебе известно, что даже если ты сделаешь ошибку, в лиспах объект,
на который нет ссылок, соберут точно. Это неотвратимо и неизбежно.
Ага, ключевые слова "на который нет ссылок".

kokoc88

Мое утверждение можно переформулировать так: "область применения C++ — пустое множество (или близко к нему)". Тем, кто считает что это не так, — пусть опишут, какой по их мнению, она является.
Она является любой. Особенно когда требуется написать качественную производительную программу со сложной логикой. Язык Си++ универсален, в этом его преимущество. Одни языки будут ужасно непроизводительными, к другим ты будешь с кровавыми слезами прикручивать GUI, третьи будут выжирать память. На Си++ ты сможешь сделать всё красиво, быстро, решить любую задачу. При этом сроки будут отличаться вовсе не в десятки раз, а дай бог в 1.5-2.

Ivan8209

>> Только если ты намеренно их сделаешь.
> Что значит намерянно? Это ошибка:
Да, "намерянно" --- это ошибка.
> ты просто забываешь где-то про ссылку. В Си++ при работе с памятью таких ошибок нет.
_Нельзя_ просто так где-то забыть ссылку.
Нельзя только оттого, что ссылки не используются _просто_так_.
Это примерно как если бы ты делал ассемблерные вставки в своих сях.
>> Ты первым вспомнил про ссылки не просто так, просто в сях без ссылок не обойтись,
>> а в высокоуровневых языках они, если вообще есть, являются средством низкоуровневым.
>> Для усиленной оптимизации и других хардкорных задач.
> Ты благополучно перепутал ссылки и указатели.
Я ничего не путал, я говорил именно про ссылки. А раз уж ты вспомнил про указатели,
то это у вас они различаются, а у нас не бывает низкоуровневых указателей просто так.
>> Кстати, да будет тебе известно, что даже если ты сделаешь ошибку, в лиспах объект,
>> на который нет ссылок, соберут точно. Это неотвратимо и неизбежно.
> Ага, ключевые слова "на который нет ссылок".
"Нет ссылок" означает "не доступен по ссылкам".
В наших краях даже циклические структуры собирают.
Это неотвратимо и неизбежно.
---
"Аллах не ведёт людей неверных."

kokoc88

Да, "намерянно" --- это ошибка.
Лол. А если просто забыл? Не уследил? То не ошибка что ли?
_Нельзя_ просто так где-то забыть ссылку

Да никто тут не говорит про просто так. Учись читать, что тебе пишут. (Впрочем, я забыл, что Кохтпы не умеют читать. Слишком увлекаются "дифференцированием простых линейных форм", вплоть до окончания обучения в ВУЗе.)
>> Ты первым вспомнил про ссылки не просто так, просто в сях без ссылок не обойтись,
>> а в высокоуровневых языках они, если вообще есть, являются средством низкоуровневым.
>> Для усиленной оптимизации и других хардкорных задач.
> Ты благополучно перепутал ссылки и указатели.
Я ничего не путал, я говорил именно про ссылки. А раз уж ты вспомнил про указатели,
то это у вас они различаются, а у нас не бывает низкоуровневых указателей просто так.

И всё-таки, ты перепутал ссылки и указатели. Да ещё и втираешь их как агрумент против утечек в языках с GC.
"Нет ссылок" означает "не доступен по ссылкам".
В наших краях даже циклические структуры собирают.
Это неотвратимо и неизбежно.

Спешу тебя порадовать (или огорчить?). Циклические структуры собирает любой GC: в Java и C# с этим тоже прекрасно справляются. Однако, это не спасает от забитых тред пулов, незавершённых соединений с БД и забытых объектов внутри списков.

myrka68

Она является любой. Особенно когда требуется написать качественную производительную программу со сложной логикой. Язык Си++ универсален, в этом его преимущество. Одни языки будут ужасно непроизводительными, к другим ты будешь с кровавыми слезами прикручивать GUI, третьи будут выжирать память. На Си++ ты сможешь сделать всё красиво, быстро, решить любую задачу. При этом сроки будут отличаться вовсе не в десятки раз, а дай бог в 1.5-2.
надеюсь, у тебя есть ОГРОМНЫЙ опыт написания логики на различных языках

Ivan8209

> Она является любой. Особенно когда требуется написать качественную производительную
> программу со сложной логикой. Язык Си++ универсален, в этом его преимущество. Одни
> языки будут ужасно непроизводительными, к другим ты будешь с кровавыми слезами
> прикручивать GUI, третьи будут выжирать память. На Си++ ты сможешь сделать всё
> красиво, быстро, решить любую задачу. При этом сроки будут отличаться вовсе не в
> десятки раз, а дай бог в 1.5-2.
Это всё реклама, со свойственным для рекламы смешением правды и лжи.
Да, если потратить кучу времени, чтобы приучить себя к постоянному ручному труду,
то можно получить отставание в полтора-два раза. Хотя умные люди уже давно
обнаружили, что скорость написания измеряется в строках за день и слабо зависит от языка.
Остальное, про графику, производительность и память --- смешно.
---
"Аллах не ведёт людей неверных."

kokoc88

надеюсь, у тебя есть ОГРОМНЫЙ опыт написания логики на различных языках
Если бы его не было, я бы не стал делать столь громких заявлений.

kokoc88

Да, если потратить кучу времени, чтобы приучить себя к постоянному ручному труду,
то можно получить отставание в полтора-два раза.
Ты всё ещё лезешь сюда с "ручным трудом"? Нет, некоторые упорно не желают изучать предмет наезда.
Остальное, про графику, производительность и память --- смешно.

А ты сопли после смеха-то подотри, да вспомни, что на дворе у нас не 70-ые годы. И что компьютерами нынче пользуются не только беспросветные лузеры. И что пользователям хочется иметь удобную программу, а не кусок гавна, в котором данные надо вбивать в консоли. Впрочем, ты даже последнюю не смог правильно написать, так что говорить дальше не о чем.

conv3rsje

А ты сопли после смеха-то подотри, да вспомни, что на дворе у нас не 70-ые годы. И что компьютерами нынче пользуются не только беспросветные лузеры. И что пользователям хочется иметь удобную программу, а не кусок гавна, в котором данные надо вбивать в консоли. Впрочем, ты даже последнюю не смог правильно написать, так что говорить дальше не о чем.
оййо
то ли дело нынешние пользователи
не чета тем дибилам что 35 лет назад кнопку тыкали
представляешь, некоторые извращенцы и сейчас почему-то пользуются консольными
и считают что это удобно
небезосновательно
"иногда лучше жевать чем говорить"

evgen5555

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

kokoc88

представляешь, некоторые извращенцы и сейчас почему-то пользуются консольными
и считают что это удобно
Ага, кто-то сверху всё время кричит про "привыкли к ручной работе".

Landstreicher

> Она является любой.
Универсальных языков программирования не бывает.
Такое высказывание выдает полное непонимание базовых принципов программирования.
2Остальные> IMHO спорить с человеком, который не понимает такой очевидной вещи — бесполезное занятие.

kokoc88

Универсальных языков программирования не бывает.
В Си++ нет чётко выраженной расположенности к решению каких-то ограниченных подзадач. Ты платишь временем разработки за возможность решить любую задачу, и сделать решение максимально производительным. Т.к. ты этого не понимаешь, Си++ для тебя является "языком без применения".

Ivan8209

>> Да, "намерянно" --- это ошибка.
> Лол. А если просто забыл? Не уследил? То не ошибка что ли?
Я думаю, что это происходит от незнания, а не от "забыл" или "не уследил".
Всё-таки, "е" и "я" находятся далеко, да и звучат по-разному.
>> _Нельзя_ просто так где-то забыть ссылку
> Да никто тут не говорит про просто так. Учись читать, что тебе пишут.
Если надо писать много низкоуровневого кода, то надо либо брать низкоуровневый язык,
либо внимательнее следить, что делаешь. Как первое, так и второе выводит за пределы
настоящего обсуждения, поскольку первое выводит за пределы сравниваемых языков,
а второе является исключительным явлением, как я и указывал раньше.
>>>> Ты первым вспомнил про ссылки не просто так, просто в сях без ссылок не обойтись,
>>>> а в высокоуровневых языках они, если вообще есть, являются средством низкоуровневым.
>>>> Для усиленной оптимизации и других хардкорных задач.
>>> Ты благополучно перепутал ссылки и указатели.
>> Я ничего не путал, я говорил именно про ссылки. А раз уж ты вспомнил про указатели,
>> то это у вас они различаются, а у нас не бывает низкоуровневых указателей просто так.
> И всё-таки, ты перепутал ссылки и указатели.
Может, покажешь, где именно?
Я нигде не использую ни прямо, ни косвенно адресной арифметики.
>> "Нет ссылок" означает "не доступен по ссылкам".
>> В наших краях даже циклические структуры собирают.
>> Это неотвратимо и неизбежно.
> Спешу тебя порадовать (или огорчить?). Циклические структуры собирает любой GC:
> в Java и C# с этим тоже прекрасно справляются. Однако, это не спасает от забитых
> тред пулов, незавершённых соединений с БД и забытых объектов внутри списков.
Единственное, что требует отдельного внимания --- это сборка ресурсов,
для чего пишут расширения к сборщику, если их ещё нет.
"Забытых объектов" --- не бывает. Если объект недоступен по ссылкам из окружения,
он является мусором и благополучно сгорает в топке. Этим и отличается среда со сбором
мусора от среды с ручным управлением памятью. Если вы к сям не смогли прикрутить
нормальный сборщик мусора, это проблема. Только не сборки мусора, а сей, потому что
соответствующие задачи прекрасно решаются в рамках высокоуровневых языков.
Кстати, поясни, как у тебя получается мусор из процессов. Блокируются, что ли?
Так на это есть общие средства разруливания.
---
"Аллах не ведёт людей неверных."

Ivan8209

>> Да, если потратить кучу времени, чтобы приучить себя к постоянному ручному труду,
>> то можно получить отставание в полтора-два раза.
> Ты всё ещё лезешь сюда с "ручным трудом"? Нет, некоторые упорно не желают изучать предмет наезда.
Ну, расскажи, когда плюсы научились мусор собирать.
Или дописывать правильный код освобождения памяти.
>> Остальное, про графику, производительность и память --- смешно.
> А ты сопли после смеха-то подотри, да вспомни, что на дворе у нас не 70-ые годы.
> И что компьютерами нынче пользуются не только беспросветные лузеры.
> И что пользователям хочется иметь удобную программу, а не кусок гавна,
> в котором данные надо вбивать в консоли.
По-твоему, со стороны программиста есть разница между вбиванием данных в консольном
диалоге и вбиванием данных в таком же диалоге, но графическом? Показывай.
Ибо не верю.
> Впрочем, ты даже последнюю не смог правильно написать, так что говорить дальше не о чем.
"Последнюю" --- это ту, про которую ты говорил раньше?
Чудо! Да ты даже такой не можешь написать.
Хотя сколько времени прошло. Это и называется, наверное, "полтора-два раза".
---
"Аллах не ведёт людей неверных."

kokoc88

Я думаю, что это происходит от незнания, а не от "забыл" или "не уследил".
Всё-таки, "е" и "я" находятся далеко, да и звучат по-разному.
Отец русской демоГОГИИ. Кто же ещё за моим правописанием уследит.
>> _Нельзя_ просто так где-то забыть ссылку
> Да никто тут не говорит про просто так. Учись читать, что тебе пишут.
Если надо писать много низкоуровневого кода, то надо либо брать низкоуровневый язык,
либо внимательнее следить, что делаешь. Как первое, так и второе выводит за пределы
настоящего обсуждения, поскольку первое выводит за пределы сравниваемых языков,
а второе является исключительным явлением, как я и указывал раньше.

Знакомьтесь: ответ в стиле "Кохтпа". Как обычно написана куча всякой ерунды, и ни слова по теме. Итак, сделаем слабую попытку вернуться к предмету обсуждения. (От которого Кохтпа пытается отдалиться, видимо, растратив все свои аргументы.) Просто так ссылку забыть нельзя. Можно сделать ошибку в своей программе. И будет утечка памяти. И GC тебя от этого не спасёт.
> И всё-таки, ты перепутал ссылки и указатели.
Может, покажешь, где именно?

Выше по тексту. Тебе говорили о забытых легальных ссылках на объекты. В языках с GC. Ты перевёл дискуссию в русло Си++ и его проблем.
Единственное, что требует отдельного внимания --- это сборка ресурсов,
для чего пишут расширения к сборщику, если их ещё нет.

О, ручная работа! Это ж на каждый вид ресурса ставить расширение к сборщику. Хорош язык, в котором такое надо делать.
"Забытых объектов" --- не бывает. Если объект недоступен по ссылкам из окружения,
он является мусором и благополучно сгорает в топке. Этим и отличается среда со сбором
мусора от среды с ручным управлением памятью.
Ты так искуссно строишь из себя тупого, что стороннему читателю будет не легко отличить. Забытые объекты бывают. Создай его и пихни куда-нибудь. И пусть он там лежит. Всё время. И в топке он не сгорит, потому что ни один GC не знает, будут ли к этому объекту обращения или нет. А они могут и быть, если объект хранится в каком-то общем хранилище, которое постоянно обрабатывается. Читай внимательнее и переспрашивай, если тебе что-то не понятно. Не надо мне рассказывать, что такое GC, как он работает и что умеет.
Если вы к сям не смогли прикрутить нормальный сборщик мусора, это проблема. Только не сборки мусора, а сей, потому что соответствующие задачи прекрасно решаются в рамках высокоуровневых языков.
В Си++ задача решается другим образом. Я тебя пытался навести на мысль, но ты, к сожалению, совсем не знаешь языка, чтобы понять, о чём я говорил всё это время. Главная тема - Си++ лучше справляется с утечками, чем языки с GC. Вот по этой теме и напиши, если есть что.
Кстати, поясни, как у тебя получается мусор из процессов. Блокируются, что ли?
Так на это есть общие средства разруливания.
У меня в Си++ уже давно не получается сделать утечек. Я приводил вполне реальный пример. Как сделать - поботай тему thread pooling.

kokoc88

Ну, расскажи, когда плюсы научились мусор собирать.
Или дописывать правильный код освобождения памяти.

Плюсы никогда не учились собирать мусор. А правильный код без мусора там давно пишут. Эту тему я тебе предлагал в качестве домашнего задания при ботании матчасти.
Ибо не верю.

А это не мои проблемы, что ты не веришь. Я не собираюсь тут прерывать твоё Добровольное Отшельничество.
Чудо! Да ты даже такой не можешь написать.

Усмири свою любовь к голословным фактам. Тему про ДНФ мы все помним, как ты там облажался помним, как ты не смог доделать программу на схеме тоже помним.

garikus

Главная тема - Си++ лучше справляется с утечками, чем языки с GC.
Очень убедительно. Не наоборот ли? Про случай с ссылкой на ненужный объект я уже написал.

Dasar

> 1, 2 - прекрасно решаются. Гораздо лучше чем в C++ или Java например.
лучше бы пример на пару строчек кода, чем демагогия в виде лучше/хуже.
> 3 - это о чем? CVS или SVN?
и об этом тоже.
предыдущие два пункта фактически тоже относились к командной работе.
так же, например, интересно:
1) как быть, если вся команда разрабатывающая продукт не имеет доступа ко всему исходному коду (например, продукт разрабатывают две разные компании).
т.е. какие есть средства построения бинарных модулей
2) как решается вопрос, с версионностью модулей (самый тяжелый случай: две разные части продукта хотят один и тот же модуль, но разных версий)
3) стыковка с другими языками (например, с C++)
а) вызов из ML плюсов (насколько я понял, это нормально работает)
b) вызов из плюсов модуля на ML
ps
>Ошибаешься, данное утверждение не верно.
...
> Гораздо лучше чем в C++ или Java например.
...
я правильно понимаю, что ты себе представляешь конструктивную дискуссию следующим образом?:
сидят две чела напротив друг друга и говорят:
первый: лучше
второй: нет хуже
первый: лучше
второй: нет хуже
или
первый: верно
второй: нет, не верно
первый: верно
второй: нет, не верно

Ivan8209

>>>> _Нельзя_ просто так где-то забыть ссылку
>>> Да никто тут не говорит про просто так. Учись читать, что тебе пишут.
>> Если надо писать много низкоуровневого кода, то надо либо брать низкоуровневый язык,
>> либо внимательнее следить, что делаешь. Как первое, так и второе выводит за пределы
>> настоящего обсуждения, поскольку первое выводит за пределы сравниваемых языков,
>> а второе является исключительным явлением, как я и указывал раньше.
> Знакомьтесь: ответ в стиле "Кохтпа". Как обычно написана куча всякой ерунды, и ни слова по теме.
> Итак, сделаем слабую попытку вернуться к предмету обсуждения.
> Просто так ссылку забыть нельзя. Можно сделать ошибку в своей программе.
> И будет утечка памяти. И GC тебя от этого не спасёт.
Если ты не понимаешь того, о чём тебе говорят, это недостаток твоего образования, а не моего.
Я тебе говорю о том, что если _намеренно_ производить действия в обход механизмов
управления памяти, то можно сделать ошибку. Работа со ссылками --- это средство
_низкоуровневой_ оптимизации. Если ты пишешь "ref" в ML, это тоже самое, что
писать "asm" в сях. Со всеми вытекающими последствиями, вплоть до разрушения стека
или нарушения защиты памяти.
>> И всё-таки, ты перепутал ссылки и указатели.
>> Может, покажешь, где именно?
> Выше по тексту. Тебе говорили о забытых легальных ссылках на объекты.
> В языках с GC. Ты перевёл дискуссию в русло Си++ и его проблем.
Лисп --- это язык со сбором мусора.
Если "забыть" ссылку на объект, последний раньше или позже будет
уничтожен сборщиком мусора. Это неизбежно и неотвратимо.
Вот это то, о чём я тебе уже говорил.
Если в сях сборщик мусора такого не умеет, то это проблемы сей, а не "языков с GC".
>> Единственное, что требует отдельного внимания --- это сборка ресурсов,
>> для чего пишут расширения к сборщику, если их ещё нет.
> О, ручная работа! Это ж на каждый вид ресурса ставить расширение к сборщику.
> Хорош язык, в котором такое надо делать.
Не на каждый, а только на элементарный, предоставляемый внеязыковыми средствами.
Это --- главное отличие от сей.
>> "Забытых объектов" --- не бывает. Если объект недоступен по ссылкам из окружения,
>> он является мусором и благополучно сгорает в топке. Этим и отличается среда со сбором
>> мусора от среды с ручным управлением памятью.
> Ты так искуссно строишь из себя тупого, что стороннему читателю будет не легко отличить.
> Забытые объекты бывают. Создай его и пихни куда-нибудь. И пусть он там лежит.
> Всё время. И в топке он не сгорит, потому что ни один GC не знает, будут ли к этому
> объекту обращения или нет. А они могут и быть, если объект хранится в каком-то общем
> хранилище, которое постоянно обрабатывается. Читай внимательнее и переспрашивай,
> если тебе что-то не понятно.
Хочешь перевести обсуждение на общий вопрос?
Если ты держишь объект в каком-то хранилище, то этот объект _запомнен_, а не забыт.
>> Если вы к сям не смогли прикрутить нормальный сборщик мусора, это проблема.
>> Только не сборки мусора, а сей, потому что соответствующие задачи прекрасно
>> решаются в рамках высокоуровневых языков.
> В Си++ задача решается другим образом.
Да, в сях управление почти полностью ручное.
> Я тебя пытался навести на мысль, но ты, к сожалению, совсем не знаешь языка,
> чтобы понять, о чём я говорил всё это время.
> Главная тема - Си++ лучше справляется с утечками, чем языки с GC.
> Вот по этой теме и напиши, если есть что.
Да нифига плюсы не справляются с утечками, утёкшая память будет возвращена только
при завершении работы, не раньше.
>> Кстати, поясни, как у тебя получается мусор из процессов. Блокируются, что ли?
>> Так на это есть общие средства разруливания.
> У меня в Си++ уже давно не получается сделать утечек.
Долго тренировался?
> Я приводил вполне реальный пример. Как сделать - поботай тему thread pooling.
Расскажи, как можно накосячить в очереди ожидания.
---
"Аллах не ведёт людей неверных."

Ivan8209

>> 1, 2 - прекрасно решаются. Гораздо лучше чем в C++ или Java например.
> лучше бы пример на пару строчек кода, чем демагогия в виде лучше/хуже.
Это обсуждалось, да и строчки приводили.
>> 3 - это о чем? CVS или SVN?
> и об этом тоже.
И чем различается употребление VCS для сей и для ML?
> так же, например, интересно:
> 1) как быть, если вся команда разрабатывающая продукт не имеет доступа ко всему
> исходному коду (например, продукт разрабатывают две разные компании).
> т.е. какие есть средства построения бинарных модулей
Для лиспов --- офигенные, для ML могу уточнить.
> 2) как решается вопрос, с версионностью модулей (самый тяжелый случай:
> две разные части продукта хотят один и тот же модуль, но разных версий)
Не хуже, чем в сях.
> 3) стыковка с другими языками (например, с C++)
> а) вызов из ML плюсов (насколько я понял, это нормально работает)
Офигенно.
> b) вызов из плюсов модуля на ML
Это не очень нужно, но если надо, есть, на худой конец, IPC.
Учитывая то, что даже сами насильники не грешат им пользоваться просто так,
даже такой исход неплох.
---
"Narrowness of experience leads to narrowness of imagination."

Landstreicher

> лучше бы пример на пару строчек кода, чем демагогия в виде лучше/хуже.
http://caml.inria.fr/pub/docs/manual-ocaml/manual004.html
Первая ссылка в Google по запросу "ocaml module system".
> и об этом тоже.
Писал программы на ML, Haskell, используя SVN. Никаких проблем не испытывал. Даже не особо понимаю, как здесь могут быть проблемы — по-моему, SVN вообще пофигу какой язык программирования.
> 1) как быть, если вся команда разрабатывающая продукт не имеет доступа ко всему исходному коду
> (например, продукт разрабатывают две разные компании).
> т.е. какие есть средства построения бинарных модулей
Можно скомпилировать так, что будет .o файл + файл с интерфейсом, а самих исходников не видно. На Haskell я этим пользуюсь постоянно, почти каждый день. На ML вроде бы тоже есть, лично не проверял.
> 2) как решается вопрос, с версионностью модулей (самый тяжелый случай: две разные части продукта > хотят один и тот же модуль, но разных версий)
Думаю что также как в C++: если слинковать каждый со своим экземпляром, то будет нормально.
> 3) стыковка с другими языками (например, с C++)
> а) вызов из ML плюсов (насколько я понял, это нормально работает)
> b) вызов из плюсов модуля на ML
(Lisp|ML|Haskell) <-> C работает прекрасно в обе стороны. Про C++ не искал, потребности не было.
> я правильно понимаю, что ты себе представляешь конструктивную дискуссию следующим образом?:
> сидят две чела напротив друг друга и говорят:
> первый: лучше
> второй: нет хуже
Я представляю себе, что в конструктивной дискуссии люди говорят по делу, то есть "можно" значит "можно за разумные деньги, в разумное время, с разумным кол-вом людей". И такой трактовки слова "можно" придерживаются обе стороны. А когда начинаются рассуждения о том, что могут сферические программы в вакууме — это уже не конструктивная дискуссия.

kokoc88

Если ты не понимаешь того, о чём тебе говорят, это недостаток твоего образования, а не моего.
Я тебе говорю о том, что если _намеренно_ производить действия в обход механизмов
управления памяти, то можно сделать ошибку. Работа со ссылками --- это средство
_низкоуровневой_ оптимизации. Если ты пишешь "ref" в ML, это тоже самое, что
писать "asm" в сях. Со всеми вытекающими последствиями, вплоть до разрушения стека
или нарушения защиты памяти.
Мля. Твой язык позволяет решить задачу: хранить список клиентов, которые к тебе конектятся по сети; каждые 3 минуты отсылать клиенту определённый пакет. Нет? Тогда язык идёт лесом. Да? Тогда в языке могут быть утечки.
> Выше по тексту. Тебе говорили о забытых легальных ссылках на объекты.
> В языках с GC. Ты перевёл дискуссию в русло Си++ и его проблем.
Лисп --- это язык со сбором мусора.
Если "забыть" ссылку на объект, последний раньше или позже будет
уничтожен сборщиком мусора. Это неизбежно и неотвратимо.
Вот это то, о чём я тебе уже говорил.
Если в сях сборщик мусора такого не умеет, то это проблемы сей, а не "языков с GC".
Речь идёт о том, что ты перепутал ссылку с указателем. (Ты опять тему перевёл. Кроме матчасти тебе надо учиться оставаться в теме. Меня твои учения о GC, мягко говоря, мало колышат. Я прекрасно знаю, что если ссылку не забыть "забыть", что является "ручной работой", то объект будет удалён GC. Если же, например, есть соединение с БД, то во время "забывания" ссылки тебе надо руками освободить это соединение. Как и любой другой ресурс.) По теме: ты перепутал ссылку и указатель.
Если ты держишь объект в каком-то хранилище, то этот объект _запомнен_, а не забыт.

Ура. До тебя начало доходить. А если ты забыл по ошибке удалить этот объект из хранилища, то получил утечку. Что и т.д.
>> Если вы к сям не смогли прикрутить нормальный сборщик мусора, это проблема.
>> Только не сборки мусора, а сей, потому что соответствующие задачи прекрасно
>> решаются в рамках высокоуровневых языков.
> В Си++ задача решается другим образом.
Да, в сях управление почти полностью ручное.

Ну вот, когда ты подучишь матчасть, мы вместе посмеёмся над этим твоим глупым заявлением.
> Я приводил вполне реальный пример. Как сделать - поботай тему thread pooling.
Расскажи, как можно накосячить в очереди ожидания.
См. выше рассуждения об утечках памяти и ресурсов. Потом ботай матчасть. Потом сможешь ответить на этот вопрос. (Подсказка: поток в тред пуле - ресурс...)

kokoc88

Главная тема - Си++ лучше справляется с утечками, чем языки с GC.
Очень убедительно. Не наоборот ли? Про случай с ссылкой на ненужный объект я уже написал.
Я могу тебе всё расписать в приваты, если действительно не понимаешь, но хочешь понять. (Я просто хочу, чтобы некоторые хотя бы немного подучили язык перед наездами на него. Сами.) Пусть пока Кохтпа поботает матчасть, т.к. ему я всё разжёвывать не собираюсь.

pirr



Да, в сях управление почти полностью ручное.
Кохтпа, я тебе чуть подскажу, что имеет ввиду Майк. У меня есть подозрения, что у него функции освобождения памяти лежат только в одном файле. В остальных файлах он нигде их явно не вызывает. И почему-то вся память мало того, что удаляется, так еще и в нужные моменты, а не когда-то в будущем. Тебе не кажется, что это хорошая автоматизация?

Причем, я уверен, что это не только у него. Думаю у большинства людей, кто работает с большими проектами, проблемы с утечкой памяти нет. Откуда она утечет, если все удаление автоматизировано "средтвами языка"?
Вот я тоже сколько времени пишу код в компании. Ни разу не писал delete или что-нить подобное. Хотя объекты в памяти завожу. И память никуда не девается, странно да? Ни разу утечки не было

bleyman

Надо вернуть флуд на место, а то что такое - 150 постов всего.
За С++: вы таки будете смеяться, но всё, что можно сделать в принципе, можно сделать и на плюсах, причём именно так, как хочется. И GC написать, и foreach с автоматическим созданием анонимного метода, и даже, наверное, closure. Разве что с динамической компиляцией кода будет тяжело. А всё потому, что в плюсах очень мощные темплейты и есть препроцессор. В результате останутся две проблемы: во-первых, код станет напоминать лисповый количеством скобочег, во-вторых, это как бы нужно либо написать и отдебажить, либо разобраться в чужом коде, причём в любом случае это лучше делать именно так, как это делается в других высокоуровневых языках. То есть плюсы, конечно, можно довести до нормального высокоуровнегого языка и получить именно его, но с неустранимой кучей скобочег и прочего мусора, зато есть сомнительная по полезности возможность увести их ещё куда-нибудь дальше самостоятельно.
Так что те, кто считают, что все насильники пишут код именно так, как его пишут второкурсники, причём не имеют возможности писать его по-другому, мягко говоря не правы. И неправы те, кто заявляет, что у плюсов очень ограниченная область применения - она, как раз, крайне большая, если вы готовы продираться сквозь синтаксический мусор (чисто синтаксический и не более того!).
В качестве бонуса - очень хорошая скорость исполнения. Я недавно экспериментировал с темплейтами, они очень милый код дают, как будто прям на ассемблере всё изначально было написано. И опять же возможность в любой момент переключиться на самый низкий уровень радует, причём вовсе не ради скорости, а ради интеропа с чем-нибудь внешним - ну, там, пару байтиков в структурке свапнуть. В связи с этим я, кстати, не очень понял, почему тут предлагают писать низкоуровневый код именно на С, а не на С++? Плюсы удобней.
Теперь про С#: вы таки посмотрите на спецификацию третьего шарпа (который уже вышел, но я на нём ещё ничего не писал). Авторы в последнее время занимаются тем, что добавляют синтаксический сахар - то есть убирают необходимость писать все эти лишние скобочечги. Например, они добавили лямбда-выражения, которые по сути совершенно идентичны анонимным делегатам, насколько я понимаю, но записываются существенно короче. Или sql синтаксис для запросов к коллекциям, который вообще разворачивается в вызовы методов текстовым преобразованием. К сожалению, по выразительной мощности он до плюсов по-прежнему немножко дотягивает, ну и ладно, зато код чище.
А теперь вопрос: кто-нибудь может мне объяснить, что имеет в виду Контра под "нормальным GC"? Я открываю файл, пишу туда что-нибудь, забываю закрыть, возвращаюсь к ожиданию команд от пользователя. Если GC не успеет собрать мусор до того момента, как я попытаюсь открыть файл снова, случатся оппаньки. Неужели можно как-то и эту проблему обойти?

Maurog

Я открываю файл, пишу туда что-нибудь, забываю закрыть, возвращаюсь к ожиданию команд от пользователя. Если GC не успеет собрать мусор до того момента, как я попытаюсь открыть файл снова, случатся оппаньки. Неужели можно как-то и эту проблему обойти?
мне кажется тут простое непонимание идеи GC. ожидание уничтожения какого-либо объекта через GC в корне не верно. То есть если один объект может создасться только после уничтожения какого-либо другого объекта, то я вижу три выхода:
1. не доверять объект коллектору (читать: мануально следить за временем жизни)
2. использовать средства синхронизации (это очень нежелательно в данном случае. напишу ниже почему)
3. перепроектировать и убрать зависимость объектов.
я считаю, что главная задача GC - это исключить излишнее использование памяти и освобождать ее по мере аппетита приложения. таким образом GC может вообще не запуститься, если ты не вылез за пределы некоторого пула (например, 20 мегабайт) и только в момент завершения приложения начнут вызываться деструкторы объектов. (по пункту 2: получается объект2 при обращении к еще незакрытому файлу может просидеть бесконечное время в ожидании закрытия файла из другого объекта)

bleyman

Я-то вполне понимаю идею GC, но Контра умеет заинтриговать =)

Landstreicher

> То есть плюсы, конечно, можно довести до нормального высокоуровнегого языка и получить именно
> его, но с неустранимой кучей скобочег и прочего мусора
...
> если вы готовы продираться сквозь синтаксический мусор (чисто синтаксический и не более того!).
Согласен, что все можно сделать. Видел lambda-выражения на C++, читал про closure итп. Кроме того — сам экспериментировал из любопытства. И работало ведь!
НО дело не в этом. Все это жутко неудобно. Язык — это инструмент, и он должен упрощать написание программ, а не усложнять его. Зачем писать тонны синтаксического мусора, если есть сотня языков, где его можно не писать?
По поводу скорости — ML и Lisp дают очень неплохую скорость, посмотри на shootout.alioth.debian.org. Всего в 1,5-2 раза медленнее чем C. Для большинства задач — это незаметно.
По поводу C# — товарищи мыслят правильно, респект. Уже есть GC, добавили лямбда-выражения, глядишь скоро сделают неплохой язык.
Кстати, mono уже умеет компилить ту версию языка, в которой есть лямбда-выражения? Если да, то я бы глянул поближе.

bleyman

> Все это жутко неудобно.
Кто ж спорит. Зато всё в одином языке, который, к тому же, всё-таки очень хорошо решает некоторые задачи.
> посмотри на shootout.alioth.debian.org
Я там увидел только вычислительные задачи. Подозреваю, что в реализации транспорта с RS-232 через TCP/IP и обратно разрыв получится посущественней =) Низкий уровень - это не быстрая арифметика, это работа с данными.
> mono уже умеет компилить ту версию языка
Неа, они почему-то всё ещё на 2.0, что, в общем, странно. Поскольку все изменения самого языка - чистый синтаксический сахар на вид.

Ivan8209

> Плюсы никогда не учились собирать мусор.
Я в курсе.
Я даже в курсе того, что они _учились_ собирать мусор.
(С учётом изменений позднего вечера.)
На все эти потуги (подсчёт ссылок и проч. "умные указатели") даже глядеть жалко.
И это всё равно не может считаться автоматическим управлением памятью:
все свои "auto_ptr" и прочие какие-то-там-ещё-"ptr" ты должен выписывать явно,
вместо того, чтобы заменить штатный "typename *".
> А правильный код без мусора там давно пишут.
Да-да, про http://rdos.net/rdos/ я тоже в курсе.
И я тоже умею писать правильный код без мусора, только это не означает,
что так писать удобнее или быстрее. Про то и речь.
---
"Аллах не ведёт людей неверных."

Landstreicher

> Кто ж спорит. Зато всё в одином языке, который, к тому же, всё-таки очень хорошо решает некоторые задачи.
Что хорошего в том, чтобы ограничивать себя только одним языком? Гораздо логичнее решать каждую подзадачу на том языке, который специально для нее заточен.

Marinavo_0507

Подозреваю, что в реализации транспорта с RS-232 через TCP/IP и обратно разрыв получится посущественней =)
Для таких задач есть Си.

bleyman

Йо, расскажи мне пожалуйста, чем С лучше С++, кроме немножко более эффективной компиляции? Или при слове С++ ты немедленно представляешь OOP чудовище с семнадцатью уровнями абстракции?
Я, правда, не читал С99, так что возможно я ошибаюсь, и они там добавили большинство приятных фишек плюсов, которых не хватает в чистом С.

nikita270601

Я, правда, не читал С99, так что возможно я ошибаюсь, и они там добавили большинство приятных фишек плюсов, которых не хватает в чистом С.
Это что за фишки, например? Если не рассматривать ООП-фичи.

Maurog

комментарии ;

nikita270601

Так их вроде давно уже добавили? Ну, в общем, в C99 однострочные комментарии точно есть.

Marinavo_0507

Ну в данном случае, если ты возьмёшься писать такую задачу "на C++" и сделаешь всё хорошо и без из**бств, то получится программа на C
Возможно, с использованием дополнительных приятных фишек.

kokoc88

На все эти потуги (подсчёт ссылок и проч. "умные указатели") даже глядеть жалко.
И это всё равно не может считаться автоматическим управлением памятью:
все свои "auto_ptr" и прочие какие-то-там-ещё-"ptr" ты должен выписывать явно,
вместо того, чтобы заменить штатный "typename *".
Ага, пишешь мне про явное выписывание смарт поинтеров, мягко переводя дискуссию в наезд на плюсы, и уходя от факта, что в языке с GC тебе ручками придётся вырисовывать освобождение ресурсов. Продолжай учить матчасть, пока что на тройку.

Marinavo_0507

и уходя от факта, что в языке с GC тебе ручками придётся вырисовывать освобождение ресурсов.
Внешних ресурсов в программе обычно используется поменьше, чем внутренних данных.
Так что наверное проще именно их освобождать руками, чем думать, какого типа указатель нужно сделать для каждого объекта.

Ivan8209

> в реализации транспорта с RS-232 через TCP/IP и обратно
RS-232 поверх TCP --- круче, наверное, только "electricity over IP".
Что означает "и обратно", я пока не осознал.
Наверное, RS-232, завёрнутый в TCP и пропущенный в итоге по тому же RS-232.
---
"Аллах не ведёт людей неверных."
P.S. Предлагаю не сравнивать возможности по написанию драйверов, это такая область,
где лучше всего может оказаться ассемблер.

Ivan8209

>> На все эти потуги (подсчёт ссылок и проч. "умные указатели") даже глядеть жалко.
>> И это всё равно не может считаться автоматическим управлением памятью:
>> все свои "auto_ptr" и прочие какие-то-там-ещё-"ptr" ты должен выписывать явно,
>> вместо того, чтобы заменить штатный "typename *".
> Ага, пишешь мне про явное выписывание смарт поинтеров, мягко переводя дискуссию в наезд на плюсы,
> и уходя от факта, что в языке с GC тебе ручками придётся вырисовывать освобождение ресурсов.
Выписывать руками придётся только в том случае, если эти ресурсы совсем новые
и отсутствуют в поставке. Это сравнимо с написанием драйвера, а для обычных ресурсов,
навроде файлов, сокетов или прочей низкоуровневой ерунды, такое уже сделано.
В отличие от сей, думать, который именно использовать "умный указатель",
как уже заметили, нафиг не надо, это --- ручная работа, которая нужна только
при усиленной оптимизации.
---
"Аллах не ведёт людей неверных."

tokuchu

Я, правда, не читал С99, так что возможно я ошибаюсь, и они там добавили большинство приятных фишек плюсов, которых не хватает в чистом С.
В C99 появились и фишки, которых нету в C++.

Ivan8209

> А всё потому, что в плюсах очень мощные темплейты и есть препроцессор.
Я в курсе, что M4 алгоритмически полон.
> В результате останутся две проблемы: во-первых, код станет напоминать лисповый количеством скобочег,
Сколько видел этот стиль, скобок получается больше.
Причём как количественно, так и качественно: кроме обычных есть угловые и фигурные.
> То есть плюсы, конечно, можно довести до нормального высокоуровнегого языка
> и получить именно его, но с неустранимой кучей скобочег и прочего мусора,
> зато есть сомнительная по полезности возможность увести их ещё куда-нибудь дальше самостоятельно.
Здравствуй, RATFOR, давно не виделись!
> Так что те, кто считают, что все насильники пишут код именно так, как его пишут второкурсники,
> причём не имеют возможности писать его по-другому, мягко говоря не правы.
Рассматриваем типичных насильников, извращенцев, вынужденных писать на сях, в расчёт не берём.
> И неправы те, кто заявляет, что у плюсов очень ограниченная область применения - она,
> как раз, крайне большая, если вы готовы продираться сквозь синтаксический мусор (чисто синтаксический и не более того!).
С этой точки зрения, ассемблер, в связке с M4, ничем не хуже.
"Если готов продираться через синтаксический мусор."
> Теперь про С#
> Авторы в последнее время занимаются тем, что добавляют синтаксический сахар -
> то есть убирают необходимость писать все эти лишние скобочечги.
То есть занимаются созданием решений "к случаю".
> А теперь вопрос: кто-нибудь может мне объяснить, что имеет в виду Контра под "нормальным GC"?
> Я открываю файл, пишу туда что-нибудь, забываю закрыть, возвращаюсь к ожиданию команд от пользователя.
> Если GC не успеет собрать мусор до того момента, как я попытаюсь открыть файл снова, случатся оппаньки.
Какие и почему?
---
"Аллах не ведёт людей неверных."

kokoc88

Выписывать руками придётся только в том случае, если эти ресурсы совсем новые
и отсутствуют в поставке. Это сравнимо с написанием драйвера, а для обычных ресурсов,
навроде файлов, сокетов или прочей низкоуровневой ерунды, такое уже сделано.
В отличие от сей, думать, который именно использовать "умный указатель",
как уже заметили, нафиг не надо, это --- ручная работа, которая нужна только
при усиленной оптимизации.
В силу специфики языков c GC тебе придётся выписывать всё руками для любого вида ресурсов. Это будет занимать гораздо больше места, чем заворачивание во врапперы в Си++. Мало того, это придётся делать всегда не в месте захвата ресурса, а где-то в стороне. Если ты этого не знаешь, продолжай учить матчасть.

Ivan8209

> В силу специфики языков c GC тебе придётся выписывать всё руками для любого вида ресурсов.
В силу специфики высокоуровневых языков, это придётся выписывать в исключительных случаях,
если тебе это непонятно, иди учи матчасть.
Если у тебя вся сборка мусора сводится к примитивному подсчёту ссылок, это не лечится.
---
"Аллах не ведёт людей неверных."

kokoc88

Внешних ресурсов в программе обычно используется поменьше, чем внутренних данных.
Так что наверное проще именно их освобождать руками, чем думать, какого типа указатель нужно сделать для каждого объекта.
Чем проще? В Си++ всю работу делают за тебя. В языках с GC эту работу делаешь ты. Потому что там, дай бог, есть только возможность просигнализировать о занятом ресурсе в момент уничтожения сборщиком объекта. Я согласен, что GC это удобно и нигде с этим не спорю. Удобно, при наличии своих минусов и подводных камней. Но писать, что в Си++ всё надо делать руками, мягко говоря - маразм.

kokoc88

В силу специфики высокоуровневых языков, это придётся выписывать в исключительных случаях,
если тебе это непонятно, иди учи матчасть.
Если у тебя вся сборка мусора сводится к примитивному подсчёту ссылок, это не лечится.
У тебя все случаи будут исключетельными. Советую тебе перечитать принципы работы GC. Тройку исправляем на твёрдую два.

Ivan8209

> В Си++ всю работу делают за тебя.
Да?
И кто за тебя закрывает хотя бы те же сокеты?
---
"Аллах не ведёт людей неверных."

Ivan8209

У меня исключительными будут случаи только когда ресурс исходно отсутствует в языке,
то есть нарушает строгую дизъюнкцию, если брать аналогии из R5RS.
_Только_ в этом случае потребуется писать освобождение, во всех остальных случаях
освобождение производится автоматически, без участия "умных указателей".
Иди учи матчасть, ты даже не в курсе, как работает сбор мусора в высокоуровневых языках.
---
"Аллах не ведёт людей неверных."

Marinavo_0507

Чем проще? В Си++ всю работу делают за тебя.
Повторяю. При создании объекта надо:
1) самому решить, в стеке или на куче его размещать; если ошибёшься - будет leak или corruption - это нормально только для низкоуровневых задач, в других случаях только мешает.
2) самому решить, какого типа указатель на него сделать - обычный или один из многочисленных смартов; если ошибёшься - будет leak или хз что похуже.
3) следить за правильностью преобразований типов указателей (я не знаток C++, но подозреваю, что если объявлен уже список типа std::list<Object *>, а у нас есть только shared_ptr на такой Object, то просто так его в этот список не положишь - рискуешь утечкой или висячий указатель).
То есть, в C++ под самыми невинными командами, которые выглядят например как простое присваивание, скрываются выделения памяти и преобразования типов, которые нельзя отдать на откуп автоматике, а надо каждый раз думать, что на самом деле там происходит.

sbs-66

Понимать, надо выделять объект на стеке или на куче - это тривиально и, я бы даже сказал, полезно. Объекты на стеке подыхают сами и за ними следить не надо. Ресурсы оборачиваем во враперы и тоже за ними не следим. На куче все объекты помещаем во владеющие хранилища и тоже не следим. Если есть много объектов не владеющих ресурсами, то можно создавать их на своей куче и не помещать во владеющее хранилище, а просто грохнуть всю кучу в конце работы, что даёт экономию на вызове деструкторов и бывает полезным.
Я не знаю, как в C# и Java с аллокаторами, но подозреваю, что пользователь не может контролировать как аллокируется память для его объектов как раз из-за пресловутого GC. Т.е. они могут использовать только стандартные средства аллокации. А во многих практических задачах написание своего аллокатора позволяет ускорить приложение на порядок за счёт отсутсвия накладных расходов из-за фрагментации и свопирования. В общем-то сила плюсов в том, что можно писать в довольно комфортных условиях на довольно высоком уровне абстракции (как минимум задумываться над удалением объектов только тогда, когда это действительно нужно) и при этом иметь возможность самому управлять самыми низкоуровневыми аспектами работы программы. Надо только один раз написать (или разобраться в чужой) библиотеку разных сущностей вроде аллокаторов, владеющих массивов, умных указателей и т.п.

Ivan8209

> Понимать, надо выделять объект на стеке или на куче - это тривиально и, я бы даже сказал, полезно.
Ещё один чукча.
Да нафиг не сдались эти низкоуровневые подробности!
Вся полезность их только в оптимизации, которая когда ещё понадобится, если понадобится вовсе.
> Объекты на стеке подыхают сами и за ними следить не надо.
Примитивное управление памятью в специальном случае.
> Ресурсы оборачиваем во враперы
Ручная работа.
> и тоже за ними не следим.
> На куче все объекты помещаем во владеющие хранилища
Ручная работа.
> и тоже не следим.
> Если есть много объектов не владеющих ресурсами, то можно создавать их на своей куче
"Своя куча" --- ещё одно место, где надо поработать руками.

> и не помещать во владеющее хранилище, а просто грохнуть всю кучу в конце работы,
"Грохнуть" --- ручная работа.
А что, если "своя куча" переполнится до окончания работы?
> что даёт экономию на вызове деструкторов и бывает полезным.
> Я не знаю, как в C# и Java с аллокаторами, но подозреваю, что пользователь не может
> контролировать как аллокируется память для его объектов
А надо ли?
Какая разница, как внутри сделаны числа: дополнением до двух или "знак-величина"?
> как раз из-за пресловутого GC. Т.е. они могут использовать только стандартные средства аллокации.
> А во многих практических задачах написание своего аллокатора позволяет ускорить приложение
Ранняя оптимизация.
> за счёт отсутсвия накладных расходов из-за фрагментации и свопирования.
За этим следит отдельная подсистема, про которую обычно достаточно знать, что она есть.
> В общем-то сила плюсов в том, что можно писать в довольно комфортных условиях
> на довольно высоком
Слишком низком.
> уровне абстракции (как минимум задумываться над удалением объектов только тогда,
> когда это действительно нужно) и при этом иметь возможность самому управлять
> самыми низкоуровневыми аспектами работы программы.
> Надо только один раз написать (или разобраться в чужой) библиотеку разных сущностей
Много ручной работы, пусть даже и одноразовой.
> вроде аллокаторов, владеющих массивов, умных указателей и т.п.
---
"Аллах не ведёт людей неверных."

Marinavo_0507

> Объекты на стеке подыхают сами и за ними следить не надо.
Если подохнут невовремя - получаешь висячий указатель.
> На куче все объекты помещаем во владеющие хранилища и тоже не следим.
Вместо new/delete используем вставку/удаление. То же самое, но другими словами.
> Если есть много объектов не владеющих ресурсами, то можно создавать их на своей куче и не помещать во владеющее хранилище, а просто грохнуть всю кучу в конце работы,
Грохнешь невовремя - получишь висячие указатели.
> что даёт экономию на вызове деструкторов
если деструктор делает что-то полезное (а это не обязательно освобождение ресурсов) - получаешь баг
В общем-то сила плюсов в том, что можно писать в довольно комфортных условиях на довольно высоком уровне абстракции (как минимум задумываться над удалением объектов только тогда, когда это действительно нужно)
Задумываться о том, как избежать проблем, указанных выше, приходится в любом случае.

enochka1145

Да нафиг не сдались эти низкоуровневые подробности!
Вся полезность их только в оптимизации, которая когда ещё понадобится, если понадобится вовсе.
А ты вообще на той же планете обитаешь, что и я (Земля)?

evgen5555

Планета-то одна, но кто-то точно витает в облаках

myrka68

Планета-то одна, но кто-то точно витает в облаках
суть ты понял! но я бы сказал не витает в облаках, а просто находится уровнем выше

Ivan8209

Насколько часто ты сталкиваешься с тем, что вся эта оптимизация,
которую ты производишь руками, востребована?
"Востребована" означает, что вот эти заморочки с разными кучами и т. п. имеют практическое значение.
---
"Аллах не ведёт людей неверных."

sbs-66

>> Объекты на стеке подыхают сами и за ними следить не надо.
> Если подохнут невовремя - получаешь висячий указатель.
Не делают указатели на объекты на стеке. Это не нужно.
>> На куче все объекты помещаем во владеющие хранилища и тоже не следим.
> Вместо new/delete используем вставку/удаление. То же самое, но другими словами.
Нет, удаления нету, только вставка. Объекты удаляются в деструкторе владеющего хранилища. Думать об этом не надо.
>> Если есть много объектов не владеющих ресурсами, то можно создавать их на своей куче и не помещать во владеющее хранилище, а просто грохнуть всю кучу в конце работы,
> Грохнешь невовремя - получишь висячие указатели.
Откуда они возьмуться, если все они жили в той же куче. Создал кучу, поработал, выделяя на ней объекты, в конце работы грохнул всю кучу со всеми указателями. Да, надо быть аккуратным и не давать ссылки на объекты этой кучи наружу. Но обычно это делать просто и такая цена за сверхэффективность вполне оправдана. На C# и Java ничего подобного ты не сделаешь.
>> что даёт экономию на вызове деструкторов
> если деструктор делает что-то полезное (а это не обязательно освобождение ресурсов) - получаешь баг
Баг где? Объектов в которых этот баг может возникнуть уже мертвы.

conv3rsje

Насколько часто ты сталкиваешься с тем, что вся эта оптимизация,
которую ты производишь руками, востребована?
да и писали уже про это
хочешь разогнать низкоуровневую часть - разгоняй
но не мешай ее с алгоритмикой

Ivan8209

>>> На куче все объекты помещаем во владеющие хранилища и тоже не следим.
>> Вместо new/delete используем вставку/удаление. То же самое, но другими словами.
> Нет, удаления нету, только вставка.
А если хранилище переполнится раньше, чем завершится программа, ага?
Мы боремся с фрагментацией и подкачкой?
---
"Аллах не ведёт людей неверных."

sbs-66

Теперь про слабости плюсов.
1. Нельзя нормально инициализировать сложные константы и статические объекты.
2. Большие проблемы со временем жизни глобальных статических объектов (надо следить, чтобы куча, на которых они выделялись, не была грохнута раньше, что длл-ка, к которой их деструктор храниться не была выгружена и т.д.) Благо статически объекты нужны редко и обычно на низком уровне вроде оконной подсистемы.
3. Дырка в слое абстракции. Я не могу завести свой класс для строк чтобы работала, например строка
myString += L"1" + L"2"

т.к. L"1" + L"2" это хрен знает что.
4. Некоторая неинтуитивнось с шаблонами, но возможно это лично моя проблема. В любом случае в других языках их вообще нет, вроде.
Минусы есть, но они не фатальны, хотя жизнь портят.

Marinavo_0507

Не делают указатели на объекты на стеке. Это не нужно.
Для временной обработки может потребоваться. Типа поместить временно в какой-нибудь уже готовый список, и пройтись по нему.
Фактически твоя фраза означает: прежде чем создавать объект на стеке, нужно понять, не понадобится ли брать на него указатель, и если да, сколько они будут жить. Это ручная работа.
Нет, удаления нету, только вставка. Объекты удаляются в деструкторе владеющего хранилища. Думать об этом не надо.
Вместе со всем хранилищем? Это может привести к утечке (как памяти, так и внешних ресурсов).
Да, надо быть аккуратным и не давать ссылки на объекты этой кучи наружу. Но обычно это делать просто и такая цена за сверхэффективность вполне оправдана.
Мы тут не за сверхэффективность боремся, а за корректную работу больших программ. В большом проекте следить, куда передаются ссылки, крайне непросто. Много ручной работы.
Баг где? Объектов в которых этот баг может возникнуть уже мертвы.
Мертвы, а деструкторы не вызваны - вот и баг.

sbs-66

Я знаю минимум два крупных проекта, где такая оптимизация неотделима от алгоритмики, т.к. эта алгоритмика жутко сложная (а я близко знаю всего 4 крупных проекта, так что 50% получается). Т.е. алгоритмы на высоком уровне работают с объектами, по окончании работы грохается куча. Никак разнести это на 2 языка С + что-то не получится, т.к. ты не заставишь С предоставлять языку высокого уровня кучу для хранения его объектов и управления её. А если и заставишь, то накладные расходы и геморой с интерфейсами съедят всё быстродействие.

sbs-66

> Для временной обработки может потребоваться. Типа поместить временно в какой-нибудь уже готовый список, и пройтись по нему.
Можно конкретный пример, где это надо. Объекты на стеке создаются внутри методов и функций и используются только внутри них. Остальные объекты сознаются на куче и передаются во владение. Это полезное разделения для програмиста и я не считаю, что от него надо непременно избавляться.
> Вместе со всем хранилищем? Это может привести к утечке (как памяти, так и внешних ресурсов).
Не может. У меня есть владеющий массив (список/дерево/хэш). В деструкторе этого хранилища удаляются все хранимые им объекты (с вызовом деструкторов, в которых освобождаются ресурсы). Утечек нет, всё делается автоматически, програмист об этом не заботится.
> Мы тут не за сверхэффективность боремся, а за корректную работу больших программ. В большом проекте следить, куда передаются ссылки, крайне непросто. Много ручной работы.
Некотрым большим программам нужна сверхэффективность определённых механизмов (в т.ч. и логики, а не низкого уровня). Плюсы позволяют её получить.
> Мертвы, а деструкторы не вызваны - вот и баг.
Нет, если объекты не владели системными ресурсами. Деструкторы нужны только для того, чтобы удобно освобождать ресурсы. Если программист хочет, он может его не вызывать. Надо только понимать, что ты делаешь. Плюсы дают возможность выбора, другие языки нет. У C# и Java вообще нет деструкторов в C++ понимании.

sbs-66

В большом проекте следить, куда передаются ссылки, крайне непросто. Много ручной работы.
Да, при передаче между DLL-ками надо использовать умные указатели с подсчётом ссылок и создавать объекты передаваемые наружу на куче вызывающей библиотеки. Это решает все проблемы.

conv3rsje

Да, при передаче между DLL-ками надо использовать умные указатели с подсчётом ссылок и создавать объекты передаваемые наружу на куче вызывающей библиотеки. Это решает все проблемы.
если честно, прочитав это первый раз я не догнал что да как
тебе сейчас опять напишут что это "ручная работа" и будут правы

sbs-66

Переключение между кучами - да, ручная. Она сводится к написанию одной строчки кода в каждом методе, вызываемом снаружи DLL'ки. Но нужно оно только для повышения эффективности. Если этого не надо, то и следить за кучами не надо. Владеющим хранилищам кучу (точнее аллокатор) можно передавать в качестве необязательного параметра шаблона (т.е. тоже только там, где мы явно решили повысить эффективность) и делается тоже изменением одной строки в одном месте.
Оборачивание объектов, передаваемых между модулями, в умный указатель - чисто грамматически сложности, никакой ручной работы. Плюс мы сразу видим, какие объекты у нас внешние, это бонус и даже повышает читаемость кода, как ни странно.
А проeктирование межмодульного взаимодействия всё равно требует размышлений, так что продумать то, как передавать данные - не проблема.

Ivan8209

> Да, при передаче между DLL-ками надо использовать умные указатели с подсчётом ссылок
Почему именно с подсчётом ссылок?
Больше способов отличить мусор не существует?
> и создавать объекты передаваемые наружу на куче вызывающей библиотеки.
То есть, надо проследить, чтобы объект создался именно на этой куче.
> Это решает все проблемы.
"Это" --- это человек, проследивший, что использованы умные указатели с подсчётом ссылок
и что объект создаётся на куче вызывающей библиотеки. Ручной труд.
---
"Аллах не ведёт людей неверных."

kokoc88

И кто за тебя закрывает хотя бы те же сокеты?
Учи матчасть.

kokoc88

У меня исключительными будут случаи только когда ресурс исходно отсутствует в языке,
то есть нарушает строгую дизъюнкцию, если брать аналогии из R5RS.
_Только_ в этом случае потребуется писать освобождение, во всех остальных случаях
освобождение производится автоматически, без участия "умных указателей".
Иди учи матчасть, ты даже не в курсе, как работает сбор мусора в высокоуровневых языках.
У тебя исключительными будут абсолютно все случаи использования ресурсов. Забить ты сможешь только на память, да и то это не освобождает тебя от обязанности следить за тем, чтобы по ошибке не осталось ссылок на ненужные объекты. Судя по тому, что ты отказываешься хотя бы примерно изучить возможности Си++ в этом плане, а так же совершенно не понимаешь особенности работы GC, твои слова про матчасть в мой адрес просто смешны.

Marinavo_0507

Можно конкретный пример, где это надо. Объекты на стеке создаются внутри методов и функций и используются только внутри них. Остальные объекты сознаются на куче и передаются во владение. Это полезное разделения для програмиста и я не считаю, что от него надо непременно избавляться.
Пример? Ну допустим, мы эвристическим методом заполняем стакан фигурками. Стакан храним в виде списка фигурок ещё с чем-нибудь.
Функция определяет какие-нибудь полезные характеристики текущего заполнения - как оно ведёт себя в разных ситуациях. Для этого она создаёт специальную тестовую фигурку (в зависимости от параметров функции добавляет её в стакан, оценивает результат (вызывая другую функцию потом удаляет фигурку. Так может делаться в цикле много раз для разных фигурок.
Естественно захотеть создавать фигурки на стеке, а список требует указатель. Мы знаем, что в конце функции из списка она будет удалена, так что функция будет работать корректно. Но это - ручная работа.
Нормальный компилятор высокоуровнего языка сам поймёт, когда можно положить структуру на стек, а ручное управление - это для низкоуровневых задач.
Передавать во владение - типично ручная работа по управлению памятью. В программах на Си так и стараются делать. В высокоуровневых языках хотелось бы чего попроще и погибче.
У меня есть владеющий массив (список/дерево/хэш). В деструкторе этого хранилища удаляются все хранимые им объекты (с вызовом деструкторов, в которых освобождаются ресурсы). Утечек нет, всё делается автоматически, програмист об этом не заботится.
Вот тебе и надо следить, чтобы лишних указателей на объекты, которые там хранятся, не появлялось. Если надо в другой список его положить на время, то изволь переделать весь владеющий массив на умные указатели. Вот и ручная работа.
Некотрым большим программам нужна сверхэффективность определённых механизмов (в т.ч. и логики, а не низкого уровня). Плюсы позволяют её получить.
Вот тут хотелось бы более содержательного описания, очень интересно.
Нет, если объекты не владели системными ресурсами. Деструкторы нужны только для того, чтобы удобно освобождать ресурсы. Если программист хочет, он может его не вызывать. Надо только понимать, что ты делаешь.
Ну допустим, один разработчик решил, что деструктор не нужен. А потом другой разработчик добавил в класс-потомок умный указатель, а не подумал, что деструктор не всегда вызовется (может, на тестовых примерах этого не проявлялось). Вот и утечка.
Да, при передаче между DLL-ками надо использовать умные указатели с подсчётом ссылок и создавать объекты передаваемые наружу на куче вызывающей библиотеки.
Всегда? Это большой оверхед, раз уж о сверхэффективности заговорили.
Только тогда, когда нужно? Это ручная работа.

Marinavo_0507

Оборачивание объектов, передаваемых между модулями, в умный указатель - чисто грамматически сложности, никакой ручной работы.
Кстати, есть данные, что подсчёт ссылок медленнее, чем многие другие способы сборки мусора. Это связано с тем, что нужна лишняя операция записи в память при каждой передаче ссылки.

sbs-66

> Почему именно с подсчётом ссылок?
> Больше способов отличить мусор не существует?
Потому что это хорошо работает во всех ситуациях. Может можно и по другому, но зачем?
> То есть, надо проследить, чтобы объект создался именно на этой куче.
Лично ты можешь вообще не переключать кучи. Тогда следить не надо. Но и грохнуть всю кучу без вызова деструторов ты не сможешь. В 90% случаев это и не надо. В C# и Java ут ебя нет возможности выбора, в с++ - есть.
> "Это" --- это человек, проследивший, что использованы умные указатели с подсчётом ссылок
и что объект создаётся на куче вызывающей библиотеки. Ручной труд.
Ну, я бы это назвал культурой програмирования и пониманием своего собстенного кода. Программист на с++ может не задумываться об аллокациях, освобождении ресурсов и т.п., но когда ему нужна эффективность он может управлять всем на более низком уровне (не вручную, как ты утверждаешь, но он должен понмать механизмы работы всего этого хозяйства). Если ты не понимаешь, как работает твой код на самом низком уровне (а ты этого не понимаешь то ты не сможешь писать эффективный код. Обычно этого не требуется, но когда требуется, то программисту на C++ не надо гемороится и переписывать свой код на другом языке и думать как его подключить и как с ним общаться из языка высокого уровня.

Marinavo_0507

> Почему именно с подсчётом ссылок?
> Больше способов отличить мусор не существует?
Потому что это хорошо работает во всех ситуациях. Может можно и по другому, но зачем?
Явное враньё
Кроме того, что это бывает медленно, оно ещё и не справляется с циклическими структурами.

sbs-66

Но она используется только для объектов, передаваемых между подсистемами, а их мало.
Если узкое место окажется в передаче объектов между подсистемами (на практике я такого не всречал то можно в данном конкретном случае оптимизировать эту передачу. С++ даёт тебе выбор.
Объекты довольно сложные сущности и потому и так уже имеют много расходов в своей реализации и передача с подсчётом ссылок для них не кретична. Где нужна эффективность, так это при передаче простых структур, но они передаются самым простым способом как часть сложных объектов и накладные расходы там минимальны. В языках высокого уровня все сущности суть объекты и сборщик мусора учитывает их все. Потому накладные расходы больше.

kokoc88

Повторяю. При создании объекта надо:
1) самому решить, в стеке или на куче его размещать; если ошибёшься - будет leak или corruption - это нормально только для низкоуровневых задач, в других случаях только мешает.
2) самому решить, какого типа указатель на него сделать - обычный или один из многочисленных смартов; если ошибёшься - будет leak или хз что похуже.
3) следить за правильностью преобразований типов указателей (я не знаток C++, но подозреваю, что если объявлен уже список типа std::list<Object *>, а у нас есть только shared_ptr на такой Object, то просто так его в этот список не положишь - рискуешь утечкой или висячий указатель).
1. Для меня слово решить ассоциируется с каким-то длительным мыслительным процессом. На стеке или в куче размещать - этот вопрос явно не подразумевает каких-либо мыслительных действий. Ровно как и не влечёт гигантских проблем, если ты вообще умеешь программировать.
2. Утечек не будет в любом случае. Опять же, процесса "принятия решения" как такового я не вижу. При этом писать придётся ровно в месте захвата ресурса, что значительно проще, чем блоки finally где-то в конце функции.
3. Просто к списку объектов надо применять другой подход.
В общем, во всех примерах ты привёл примеры-проблемы того, как можно напортачить на Си++. Проще уж было тогда написать *char*)NULL) = '0'; и кричать, какой Си++ плохой язык. Не спорю, если не умеешь на нём программировать и не изучил тему, то твои вопросы могут быть уместны. Впрочем, таким горе-программистам GC обычно нисколько не помогает - программы просто валятся с исключениями.

sbs-66

Сборщики мусора, которые справляются с циклическими структурами работают ещё медленнее, насколько я знаю. По моему половина сборщиков мусора как раз по этой причине с циклическими структурами не справляются. Если я не прав - поправьте.
Я говорил про практику. На практике люди не создают циклических структур из интерфейсов, передаваемых между подсистемами. Обычно передаются вообще атомарные данные не завязанные в сложные связи. В крайнем случае массивы. Если передают более сложную структуру данных, то создают объект-хранилище, который эти данные и связи между ними хранит, а не строят ручками циклические цепочки.
Хотя да, в С++ надо понимать кто кем владеет. Но я не считаю это большим минусом, так как обычно это как раз улучшает понимание того, как устроен механизм.
Понимать, кто кем владеет и ручками удалять объекты - это две большие разницы. Понимание это не требует ручной работы, но лишь дисциплинирует.

kokoc88

суть ты понял! но я бы сказал не витает в облаках, а просто находится уровнем выше
Ну если только высоту мерять глубиной канализации.

Marinavo_0507

В языках высокого уровня все сущности суть объекты и сборщик мусора учитывает их все. Потому накладные расходы больше.
Это только в Java все сущности - объекты.
Накладные расходы запросто могут быть гораздо меньше, чем удаление развестистых структур путём их обхода. Хотя конечно побольше, чем грохнуть специализированную кучу целиком.

sbs-66

Да. Ещё это понимание кто кем владеет необходимо только на этапе проэктирования системы классов, обычно. При реализации методов над этим думать не приходится. Но проектирование классов в любом случае требутеся, и обычно оно включает в себя построение иерархии, т.е. понимание того, кто кем владеет.

sbs-66

Разве структуры в C# не собираются сборщиком мусора?

Marinavo_0507

1. Для меня слово решить ассоциируется с каким-то длительным мыслительным процессом. На стеке или в куче размещать - этот вопрос явно не подразумевает каких-либо мыслительных действий. Ровно как и не влечёт гигантских проблем, если ты вообще умеешь программировать.
2. Утечек не будет в любом случае. Опять же, процесса "принятия решения" как такового я не вижу. При этом писать придётся ровно в месте захвата ресурса, что значительно проще, чем блоки finally где-то в конце функции.
Много мелких действий отнимают время и создают нагрузку на мозг ничуть не хуже одного длительного мыслительного процесса. Если тебе кажется, что они не влекут проблем - то это оттого, что ты не представляешь, как оно - обходиться без этого.
Факт же состоит в том, что способ создания объекта и тип указателя на него нужно задавать явно - это не машина решает, а лично ты - то есть слово "решить" верное.
3. Просто к списку объектов надо применять другой подход.
Ага, и заботится об этом опять же разработчик.
Применит один подход, а потом окажется, что часть объектов списка "приходят из других подсистем" и там умные указатели, потому что ту подсистему спроектировал - добро пожаловать, рефакторинг!

Ivan8209

> Забить ты сможешь только на память, да и то это не освобождает тебя от обязанности следить за тем,
> чтобы по ошибке не осталось ссылок на ненужные объекты.
Да не нужно это отслеживать!
Ты сам себе придумываешь грабли, помещая обрабатываемые данные в какие-то свои списки,
хеши, кеши и другие кучи, а потом говоришь, что нужно следить. Не делают так.
Не таскают за собой постоянно такую уйму данных, если она не нужна.
А мемоизация и кеширование --- вполне высокоуровневые понятия.
Если ты вместо кеширования используешь мемоизацию, то это твои личные трудности,
проистекающие из-за того, что ты за своей реализацией не видишь простой абстракции.
Кстати, ещё одно свидетельство того, что ты проделал большую ручную работу:
и мемоизация, и кеширование являются такими вещами, которые делаются один раз
и надолго.
---
"Аллах не ведёт людей неверных."

Marinavo_0507

Я говорил про практику. На практике люди не создают циклических структур из интерфейсов, передаваемых между подсистемами. Обычно передаются вообще атомарные данные не завязанные в сложные связи. В крайнем случае массивы. Если передают более сложную структуру данных, то создают объект-хранилище, который эти данные и связи между ними хранит, а не строят ручками циклические цепочки.
Прикинь, как атомарные структуры и массивы из них, так и глобальный объект-хранилище (где данные и связи опять же снаружи видны как атомарные структуры) отлично позволяет писать разные подсистемы на разных языках.
Интересен как раз случай, когда эти связи глобальны, но распределены между подсистемами.

sbs-66

Кстати, все Java программы, которые я запускал под виндой, были тормознутыми шо пездец и имели какой-то чрезжопный пользовательский интерфейс. Я думаю, что это показатель ущербности языка и пропагандируемо им подхода. Недаром большая часть Java-проектов - это бизнес-приложения для штучных клиентов, которыми пользуются люди только на работе и только из-за того, что у них нет выбора (работа такая).
Зато большая часть коробочных продуктов написаны на плюсах. Потому что эти продукты люди покупают для себя, и Java-кодеры не могут конкурировать, если их програма менее удобна или в 2 раза медленне.
На C# я пока серьёзных проeктов не видел. Где он используется так вот прямо и не знаю даже. Наверное в той же нише, что и Java.
Остальные языки высокого уровня, про которые тут говорили, вроде как вообще по большей части интерпретируемые и используются либо для веб-серверов (где ресурсоёмких алгоритмических задач обычно нет, а всё сводится к нескольким запросам к БД либо для всяких скриптов конфигурационных, где задачи ещё проще.

sbs-66

Интересен как раз случай, когда эти связи глобальны, но распределены между подсистемами.
Например?

Marinavo_0507

Кстати, все Java программы, которые я запускал под виндой, были тормознутыми шо пездец и имели какой-то чрезжопный пользовательский интерфейс. Я думаю, что это показатель ущербности языка и пропагандируемо им подхода.
Аналогично, только линукс вместо винды.
Правда, сейчас должны набежать любители этого дела, и доказывать, что мы неправильно понимаем, что такое тормоза, и что такое хороший интерфейс
Недаром большая часть Java-проектов - это бизнес-приложения для штучных клиентов, которыми пользуются люди только на работе и только из-за того, что у них нет выбора (работа такая).
А разве это неверно чуть ли не для любого языка?
То есть хоть на C++ много коробочных продуктов, но внутренних - ещё больше.

sbs-66

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

sbs-66

На С++ подавляющее большинство коробочных продуктов. А это показатель.

sbs-66

Кстати. Вот для чего С++ плох, так это для веб-приложений. Тут гораздо удобнее PHP, Perl + библиотеки или ещё что из той же серии (Ruby, Phyton). "Ещё что" я не пробовал, но первые 2 дадут 100 очков форы.

kokoc88

Не таскают за собой постоянно такую уйму данных, если она не нужна.
Не переводи тему. Если не нужна - не таскают. А если нужна, то таскают. Если ты не писал программ, которые обрабатывают что-то большее, чем одна строка текста - это твои проблемы, твой узкий взгляд на мир.
Кстати, ещё одно свидетельство того, что ты проделал большую ручную работу:
и мемоизация, и кеширование являются такими вещами, которые делаются один раз
и надолго.
Я вижу только одно свидетельство: кто-то снова начал сыпать дурацкими словечками. Видимо, в детском саду переучили "дифференцировать простые линейный формы". Короче, ты опять пустозвонишь не по теме. Кроме матчасти советую тебе подучить литературу. Может быть, люди начнут тебя понимать. Впрочем, тебе этого не надо. Ведь тогда они начнут понимать, что знаний в твоей голове - ноль без минуса.

Marinavo_0507

Такие проблемы решаются ещё на этапе проектирования.
Ты следуешь методу водопада?
то надо просто все созданные внутри элементы тоже обернуть в умный указатель и сделать список из них
"просто", гм
на такие простые дейстия можно всю жизнь потратить
Но это все решается ещё до начала написания кода, обычно.
Обычно когда одну подсистему уже почти сделаешь, требования меняются, и интерфейс надо пересматривать

Dasar

> Можно конкретный пример, где это надо. Объекты на стеке создаются внутри методов и функций и используются только внутри них.
любые структуры переменной длины (строки, коллекции и т.д.)

Marinavo_0507

На С++ подавляющее большинство коробочных продуктов. А это показатель.
Показатель того, что для других приложений (которых большинство) он плохо пригоден? Кому-то же понадобилось все остальные языки изобретать
Ну и в разговоре о том, "как надо", ссылаться на большинство - методологически неправильно. Большинство живёт так себе, а каждый хочет жить лучше

sbs-66

Не понял.
Ну создал я строку на стеке, она на стеке живёт. Другое дело что в ней храниться указатель на буфер, который уже на куче (специальной куче для строк со специальным аллокатором для повышения производительности, привет). Никаких проблем не вижу.

kokoc88

Много мелких действий отнимают время и создают нагрузку на мозг ничуть не хуже одного длительного мыслительного процесса. Если тебе кажется, что они не влекут проблем - то это оттого, что ты не представляешь, как оно - обходиться без этого.
Факт же состоит в том, что способ создания объекта и тип указателя на него нужно задавать явно - это не машина решает, а лично ты - то есть слово "решить" верное.
Много мелких действий у тебя будет в любом проекте, код которого занимает более одного файла. На любом языке. В частности, в языках с GC тебе придётся следить за освобождением ресурсов, исключениями и наличием забытых ссылок на объекты. В Си++ за тебя всю работу сделают деструкторы. (Исходя из практики: Си++ ни в одном моём коммерческом проекте не течёт, и даже не начинал. А вот в языках с GC c этим были проблемы. Нет, я не принимаю во внимание кучу проектов, где память течёт. Там пишут промышленный код Кохтпы, которые не ботали матчасть.)
Ага, и заботится об этом опять же разработчик.
Применит один подход, а потом окажется, что часть объектов списка "приходят из других подсистем" и там умные указатели, потому что ту подсистему спроектировал - добро пожаловать, рефакторинг!
Шаблоны. Edit: в смысле не те, что в программировании. Когда к тебе что-то из других систем приходит, простые указатели не хранят. Рефакторинг ты написал с восклицательным знаком, правильно. GC от рефакторинга нисколько не спасает.

sbs-66

Коробочные продукты - это чуть ли не единственный софт, который реально конкурирует друг с другом за пользователя. Т.е. такой, который стремяться делать быстрым, удобным и безглючным. Бизнес-программы навязываются. Программы стоимостью больше $5000 выбираются уже не по своим качествам. Свободный софт не заинтересован в пользователе и не конкурирует. Какие там ещё ниши есть?
И раз большинство коробочного софта написано на С++, то значит на нём выгоднее писать удобный и быстый софт. Выгоднее - это значит поддержка и развитие кода требует меньше человеко-месяцев, чем на других языках (связках языков). По крайней мере на тот момент, кога проект начинался. Не бесспорный показатель, но значимый.

sbs-66

"просто", гмна такие простые дейстия можно всю жизнь потратить
Ну знаешь ли... Обычно это 1 место в коде где элементы списка создаются + одна строка где объявляется сам спискок. В редких случаях есть несколько мест, где создаются элементы списка, но это опять таки два, три, максимум пять мест. Если мест больше, значит ты что-то неправильно спроектировал.

Marinavo_0507

Обычно это 1 место в коде где элементы списка создаются
В C++ надо менять тип во всех местах, где он используется, а вот их запросто может быть больше.
Шаблоны не спасают, так как инстанциировать их же всё равно надо, указывая тип руками, и надо заранее знать, что вот тут тип может поменяться, поэтому надо не просто поле или параметр написать, а шаблон сделать.

Ivan8209

>> Почему именно с подсчётом ссылок?
>> Больше способов отличить мусор не существует?
> Потому что это хорошо работает во всех ситуациях.
На самом деле, это работает и плохо, и медленно.
> Может можно и по другому, но зачем?
Чтобы, например, можно было использовать циклические структуры в их естественном представлении.
>> То есть, надо проследить, чтобы объект создался именно на этой куче.
> Лично ты можешь вообще не переключать кучи. Тогда следить не надо.
> Но и грохнуть всю кучу без вызова деструторов ты не сможешь.
> В 90% случаев это и не надо. В C# и Java ут ебя нет возможности выбора, в с++ - есть.
Ты опять говоришь про низкоуровневые языки.
Если твои объекты слишком велики, то ты навряд ли доживёшь до того времени,
когда тебе можно будет грохнуть специализированную кучу целиком,
просто потому что придётся мусор собирать.
А так, нормальные люди уже давно память выделяют для мелких объектов одну,
а для больших --- другую, соответственно, раздельная куча и не нужна, и приводит
лишь к потерям эффективности.
Раздельные кучи могут быть полезны только в некоторых _специальных_ случаях,
но это совсем другая история.
>> "Это" --- это человек, проследивший, что использованы умные указатели с подсчётом ссылок
>> и что объект создаётся на куче вызывающей библиотеки. Ручной труд.
> Ну, я бы это назвал культурой програмирования и пониманием своего собстенного кода.
Ну да, нехватка технических возможностей возмещается более строгим управлением ---
ручной труд.
Такие же возражения были и против Дейкстры, когда тот устроил поход против переходов.
Вроде того, "можно научиться (мы научились) писать так, чтобы было более или менее понятно."
> Если ты не понимаешь, как работает твой код на самом низком уровне (а ты этого не понимаешь
> то ты не сможешь писать эффективный код.
Это неправда.
Если грамотно производить замеры, то можно производить грамотные замены.
> Обычно этого не требуется, но когда требуется, то программисту на C++ не надо гемороится
> и переписывать свой код на другом языке и думать как его подключить
> и как с ним общаться из языка высокого уровня.
Вот именно, что "когда потребуется". Только приплюснутый насильник задолго до этого
"потребуется" хорошо попарился над написанием кода.
---
"Аллах не ведёт людей неверных."

Dasar

> Ну создал я строку на стеке, она на стеке живёт
например, в метод OpenFile ты что передаешь?
а в GetCurrentDirectory?
а в StringFromClsid?
а в какой-нибудь ICertEncodeAltName::GetName?

sbs-66

typedef спасёт отца русской демократии.
Хотя да, если заранее не предусмотреть - придётся поменять в нескольких местах.
Но это делается без проблем, благо компилятор все эти места покажет.

kokoc88

>> Почему именно с подсчётом ссылок?
>> Больше способов отличить мусор не существует?
> Потому что это хорошо работает во всех ситуациях.
На самом деле, это работает и плохо, и медленно.
OMFG, прекрати уже гнать в этой ветке и иди ботать тему.

sbs-66

const CUnicodeString& или CUnicodeString, смотря откуда вызываются.
Если нужен буфер для чтения, то CUnicodeString.Ptr. Если для записи, то метод, которому передаю максимальный размер буфера, который может понадобиться, а он мне возвращает неконстантный буфер, после использования вызываю метод, "замораживающий" буфер обратно и перевычисляющий внутренние инварианты. Если нужна строка для COM-интерфейсов, то оборачиваю в неё.

Ivan8209

> И раз большинство коробочного софта написано на С++, то значит на нём выгоднее писать удобный и быстый софт.
Выгоднее _кому_?
> Выгоднее - это значит поддержка и развитие кода требует меньше человеко-месяцев, чем на других языках (связках языков).
Совсем не значит.
"Значит" было бы, если бы с других языков переходили на С++, чего я не видел ни разу,
точно так же ни разу и не слышал. Языки группы сей я в расчёт не беру.
---
"Аллах не ведёт людей неверных."

Marinavo_0507

Коробочные продукты - это чуть ли не единственный софт, который реально конкурирует друг с другом за пользователя. Т.е. такой, который стремяться делать быстрым, удобным и безглючным. Бизнес-программы навязываются. Программы стоимостью больше $5000 выбираются уже не по своим качествам.
То же самое можно ведь и другими словами сказать.
Программы дороже $5000 и бизнес-программы в ряде случаев являются чем-то новым, решают задачу, которую раньше решать не умели.
А коробочные, да которые ещё конкурируют, это предметы массового спроса, где все методы давно известны, и надо только грамотно реализовать, управляя своими расходами, чтоб получить максимальную прибыль. Вон как говорит : "нужно всего лишь понимать, что делаешь, следить за собой, уметь программировать, работать аккуратно", то есть думать нечего - надо качественно и энергично трясти
Лучше расскажи, откуда взялись примеры со специальной кучей.
Может быть, там "всего лишь" опять же надо было правильно спроектировать, и проблема бы исчезла. Ты в курсе, что хорошие GC освобождают развесистые структуры быстрее (по крайней мере, обещают это чем полный обход и вызов delete для каждого узла? Может, если проверить, то и с твоей задачей нормально бы справились?

Ivan8209

Иди учи основы, можешь начать даже отсюда.
---
"Аллах не ведёт людей неверных."

sbs-66

То же самое можно ведь и другими словами сказать.Программы дороже $5000 и бизнес-программы в ряде случаев являются чем-то новым, решают задачу, которую раньше решать не умели.
На практике это не так. Продукты дороже $5000 не может купить рядовой менеджер, решение о покупке принимают начальники высокого уровня, которым специальные отделы маркетинга впаривают свой продукт по полной (с походами в сауну и т.п.). На самом деле от 5000 до 20000 просто нет продуктов. Либо меньше 5000 цена, либо 20 000-50 000 сразу. И на качество продукта там уже не смотрят. Нашёлся критический глюк - исправляют. А удобство тех, кто будет этим пользоваться никого не волнует. В половине случаев продукт даже не используют, на самом деле...
Лучше расскажи, откуда взялись примеры со специальной кучей.Может быть, там "всего лишь" опять же надо было правильно спроектировать, и проблема бы исчезла. Ты в курсе, что хорошие GC освобождают развесистые структуры быстрее (по крайней мере, обещают это чем полный обход и вызов delete для каждого узла? Может, если проверить, то и с твоей задачей нормально бы справились?
А чего рассказывать. В одном случае строится очень большой граф линейного деления с кучей оптимизаций и ищется наилучшее деление по оценочной функции. После нахождения весь граф грохается вместе с кучей, что экономит кучу вызовов деструкторов, позволяет не заботится о владении и решает проблемы с фрагментацией памяти.
В другом случае ещё более сложный перебор сложных древовидных объектов (И/ИЛИ-деревья) с тем же результатом.
Плюс ещё иногда пишут специально быстрый аллокатор, который не заботится о фрагментации (иногда это очень накладно после работы кучу, на которой он работал грохают и создают заново. Это экономит время, так как грохнуть 1 раз оказывается выгоднее, чем бороться с фрагментацией памяти по ходу.
А хорошая GC хороша в стандартных случаях. В маргинальных же случаях программисту выгоднее действовать руками, т.к. он знает как устроена алокации и деаллокации в его проекте, а GC об этом знать неоткуда.

kokoc88

Иди учи основы, можешь начать даже отсюда.
Ага, уже прогресс. Ты стал интересоваться темой. Теперь тебе остаётся просто прочитать про reference counting, затем про garbage collection, а затем вместе мы посмеёмся над всем маразмом, который ты написал в этом топике.

enochka1145

Кстати, все Java программы, которые я запускал под виндой, были тормознутыми шо пездец и имели какой-то чрезжопный пользовательский интерфейс. Я думаю, что это показатель ущербности языка и пропагандируемо им подхода.
Как говорят в американских фильмах, "ты думаешь неправильно". Строго говоря, отсюда следует только то, что все Java-программы, которые то запускал под виндой, были тормознутыми шо пездец и имели какой-то чрезжопный пользовательский интерфейс. Ничего более.
Чтобы Java-программы работали быстро и выглядели круто, нужно просто писать по человечески и использовать правильные библиотеки. Например, SWT, которая даже поставляется в комплекте с SUSE Linux.
То, что Java простой, не освобождает от необходимости думать головой.

Ivan8209

Я очень хорошо знаю подноготную, давай рассказывай, откуда ты взял,
будто подсчёт ссылок быстрый или надёжный способ учёта памяти.
Чтобы не забыл по дороге, разговор шёл так:
K> Почему именно с подсчётом ссылок?
K> Больше способов отличить мусор не существует?
> Потому что это хорошо работает во всех ситуациях.
K> На самом деле, это работает и плохо, и медленно.
M> OMFG, прекрати уже гнать в этой ветке и иди ботать тему.
---
"Аллах не ведёт людей неверных."

enochka1145

Аналогично, только линукс вместо винды.
Правда, сейчас должны набежать любители этого дела, и доказывать, что мы неправильно понимаем, что такое тормоза, и что такое хороший интерфейс
Господа, давайте 1 HW / тред.
// KDE - мегаотстой. Хуже только Gnome и прочие FVWM-ы

sbs-66

Ну, я таких не видел. Можешь пару примеров известных нетормознутых прог на Java привести?

SPARTAK3959

Competition Arena (клиент для соревнований TopCoder yEd Graph Editor.

Marinavo_0507

А чего рассказывать. В одном случае строится очень большой граф линейного деления с кучей оптимизаций и ищется наилучшее деление по оценочной функции. После нахождения весь граф грохается вместе с кучей, что экономит кучу вызовов деструкторов, позволяет не заботится о владении и решает проблемы с фрагментацией памяти.
В другом случае ещё более сложный перебор сложных древовидных объектов (И/ИЛИ-деревья) с тем же результатом.
Тогда я не понимаю, зачем там C++. На C будет выглядеть так же, если тут всё дело в алгоритме.
И ещё не понимаю, почему управление памятью (сложность, условно говоря, O(n вносит существенный вклад во время работы сложного алгоритма - то есть заведомо сложнее O(n).

Marinavo_0507

На практике это не так. Продукты дороже $5000 не может купить рядовой менеджер, решение о покупке принимают начальники высокого уровня, которым специальные отделы маркетинга впаривают свой продукт по полной (с походами в сауну и т.п.). На самом деле от 5000 до 20000 просто нет продуктов. Либо меньше 5000 цена, либо 20 000-50 000 сразу. И на качество продукта там уже не смотрят. Нашёлся критический глюк - исправляют. А удобство тех, кто будет этим пользоваться никого не волнует. В половине случаев продукт даже не используют, на самом деле...
Когда никого ничего не волнует - это другой вопрос.
Рядового менеджера очень часто тоже не особо волнует такое - купит то, у чего реклама лучше.
А если дорогой продукт покупается для дела - это значит, что решить задачу меньшими затратами нельзя, что в свою очередь значит, что задача очень сложная.

Marinavo_0507

KDE - мегаотстой. Хуже только Gnome и прочие FVWM-ы
если уж на то пошло, то на яве вообще достойных альтернатив нет
так называемая Java Desktop System - это GNOME, упакованный сантехниками
даже браузер не осилили сделать, хотя, казалось бы, наилучшее применение было бы для этого языка, и hotjava подавала определённые надежды

kokoc88

Я очень хорошо знаю подноготную, давай рассказывай, откуда ты взял,
будто подсчёт ссылок быстрый или надёжный способ учёта памяти.
Чтобы не забыл по дороге, разговор шёл так:
K> Почему именно с подсчётом ссылок?
K> Больше способов отличить мусор не существует?
> Потому что это хорошо работает во всех ситуациях.
K> На самом деле, это работает и плохо, и медленно.
M> OMFG, прекрати уже гнать в этой ветке и иди ботать тему.
Ага, мои слова относились к твоему глупому коментарию. Если ты не можешь понять, почему он глупый, продолжай штудировать матчасть.

kokoc88

Ну, я таких не видел. Можешь пару примеров известных нетормознутых прог на Java привести?
Ты, скорее всего, нарвался на GUI решения на Java. Они отличаются такими проблемами. Серверные решения гораздо более быстрые.

Ivan8209

K> Я очень хорошо знаю подноготную, давай рассказывай, откуда ты взял,
K> будто подсчёт ссылок быстрый или надёжный способ учёта памяти.
K> Чтобы не забыл по дороге, разговор шёл так:
K> Почему именно с подсчётом ссылок?
K> Больше способов отличить мусор не существует? (1)
> Потому что это хорошо работает во всех ситуациях.
K> На самом деле, это работает и плохо (2 и медленно (3).
M> OMFG, прекрати уже гнать в этой ветке и иди ботать тему.
M> Ага, мои слова относились к твоему глупому коментарию.
M> Если ты не можешь понять, почему он глупый, продолжай штудировать матчасть.
К которому из?
Я даже тебе цифирки поставил. Надеюсь, ты их прочитать сможешь.
Либо укажи сам. Если ты действительно разбираешься в теме, тебе это будет нетрудно.
---
"Аллах не ведёт людей неверных."

Landstreicher

> Ну, я таких не видел. Можешь пару примеров известных нетормознутых прог на Java привести?
+1
тоже ни разу не видел нормальных прог на Java (в любых областях)

Marinavo_0507

Серверные решения гораздо более быстрые.
По сравнению с монстрами на PHP что угодно быстрым покажется.
А кстати, Java уже научилась на ходу менять классы на новые версии?
Вроде бы у конкурирующих технологий такой проблемы нет.

Marinavo_0507

на мобилах вроде нормальные проги

myrka68

Ты, скорее всего, нарвался на GUI решения на Java. Они отличаются такими проблемами. Серверные решения гораздо более быстрые.
а можно пример этих серверных решений? реально, _очень_ хочется узнать _хотя_бы_ одно решение

myrka68

на мобилах вроде нормальные проги
наверное, просто сравнивать не с чем

sbs-66

Тогда я не понимаю, зачем там C++. На C будет выглядеть так же, если тут всё дело в алгоритме.И ещё не понимаю, почему управление памятью (сложность, условно говоря, O(n вносит существенный вклад во время работы сложного алгоритма - то есть заведомо сложнее O(n).
С++ потому что удобнее и ООП. Зачем C я вообще не понимаю.
O(n) - это неправильная оценка. Зависит от аллокатора. В прохом случае могут получиться существенные тормоза, если для аллокации каждого объекта будет перелопачиваться вся куча. Плюс что ты называешь n? Если число аллокаций, то оно может быть очень велико по отношению к сложности всего алгоритма. И если каждая алокация будет занимать сильно больше O(1 то всё будет тормозить.

Marinavo_0507

С++ потому что удобнее и ООП.
зачем ООП на вычислительных алгоритмах?
я ещё понимаю, метапрограммирование
Зачем C я вообще не понимаю.
для низкоуровневых задач,
чтоб незаметно для себя на те же выделения памяти не нарываться, которые, как ты сказал, в плохих случаях будут небыстрыми
и ещё ввиду относительной простоты языка существуют простые же и свободные парсеры, с помощью которых можно расширить C, сделав свой DSL
это если захочется метапрограммирования, встроенного препроцессора не хватит, а m4 не понравится
Если число аллокаций, то оно может быть очень велико по отношению к сложности всего алгоритма.
Не забывай, что ты всю кучу грохаешь целиком в самом конце.
Это значит, что число аллокаций (именно тех, на которых ты экономишь настолько мало, что для всех них хватает памяти одновременно.
В прохом случае могут получиться существенные тормоза, если для аллокации каждого объекта будет перелопачиваться вся куча.
В твоей задаче этого легко избежать, если действительно вылезет такая проблема.

Marinavo_0507

сравнивать можно со встроенными, которые наверное не на яве
и с софтом для виндового кпк, который тоже не на яве

ava3443

А кстати, Java уже научилась на ходу менять классы на новые версии?
Вроде бы у конкурирующих технологий такой проблемы нет.
можно с этого места подробнее?
я туплю, или это все J2EE-контейнеры умеют?

kokoc88

К которому из?
Я даже тебе цифирки поставил. Надеюсь, ты их прочитать сможешь.
Либо укажи сам. Если ты действительно разбираешься в теме, тебе это будет нетрудно.
Нееет. Ты сам давай думай, почему написал маразм. Тебе что-то объяснять - себе дороже. Такого тукана - только отсылать на самоподготовку.

poi1981

>сам давай думай
как ты можешь такое требовать, это ж ручной труд

Marinavo_0507

не знаю, кто тупит, я же не в теме
насколько я понимаю, загрузка классов на лету поддерживается VM
а вот обратно его выгрузить, чтоб загрузить новую версию, возможно как-то?
в чём заключается суть контейнера - я за 5 минут понять не смог, но никаких данных о том, что он расширяет возможности VM, пока что не увидел

ava3443

я тоже не в теме, так что ждём отцов
а вот обратно его выгрузить, чтоб загрузить новую версию, возможно как-то?
я так представлял себе, что надо свой classloader использовать.
понадобилось загрузить новую версию - похерил старый classloader, загрузил в новом.

Dasar

> А кстати, Java уже научилась на ходу менять классы на новые версии?
> Вроде бы у конкурирующих технологий такой проблемы нет.
JIT-ные в том числе?

Marinavo_0507

не понял вопрос

Marinavo_0507

насколько я себе представляю, ClassLoader что-то делает, а потом результат его работы регистрируется в VM под нужным именем класса и всё

conv3rsje

Ты, скорее всего, нарвался на GUI решения на Java. Они отличаются такими проблемами. Серверные решения гораздо более быстрые.
угу
от 20 до 40 секунд для ogsa dai чтоб выдал список из одного ресурся (пара урлов)
это я понимаю, enterprise...

Dasar

на сколько я помню, замену на лету версий плохо поддерживают те языки/framework-и, которые:
1. Поддерживают JIT-компиляцию
2. предоставляют прозрачную стыковку с другими языками/framework-ами в едином адресном пространстве

Marinavo_0507

ну вот хз
как на практике - я не в теме
а теоретически - не вижу, почему JIT как-то на это должен влиять
native код или байткод - нет большой разницы, от чего память освобождать
гораздо интереснее, что делать с активными объектами класса, который удаляется
тут есть несколько вариантов разумных, можно в принципе эту фичу настраиваемой сделать

Marinavo_0507

ну и по поводу 2
java ничего прозрачного не предоставляет, да и я не знаю таких примеров, чтоб два достаточно разных (C и C++ не в счёт, то есть) языка прозрачно стыковались

Dasar

> native код или байткод - нет большой разницы, от чего память освобождать
есть, т.к. JIT - может код из разных классов заменить на одну asm-инструкцию, соответственно достаточно геморройно потом это растаскивать обратно
например:

//c1.dll
class C1
{
public static int GetWidth
{
return 10;
}
};
//c2.dll
class C2
{
public static int GetSquare
{
return C1.GetWidth * 6;
}
};
//c3.exe
class Program
{
static void Main
{
int square = C2.GetSquare;
}
}

весь это код Jit-ом заменится на

move square, 60

далее, при вкатывании новой версии класса C2 надо очень аккуратно весь код перегенерить

Marinavo_0507

далее, при вкатывании новой версии класса C2 надо очень аккуратно весь код перегенерить
ну это вроде не сложнее сборки мусора - определить, какой код надо перегенерить (в случае jit - скорее выбросить, перегенерится он потом сам)

Landstreicher

Это от мобилы зависит. У меня, например, все страшно тормозит.

Marinavo_0507

Ну типа если мобила тормозная, то там всё тормозит, не только ява.
А если нормальная, то и ява удивительно быстро работает.

Landstreicher

> весь это код Jit-ом заменится на
Это в теории? Или ты сам на практике такой JIT видел?

Landstreicher

> от 20 до 40 секунд для ogsa dai чтоб выдал список из одного ресурся (пара урлов)
> это я понимаю, enterprise...
Чтобы платили большое бабло, нужно создать видимость большой работы. Поэтому и работает долго.

Marinavo_0507

Чтобы платили большое бабло, нужно создать видимость большой работы. Поэтому и работает долго.
Точно! Enterprise-level - это означает, что разработчику не нужно вставлять в свою программу пустые циклы - нужные тормоза фреймворк или VM создаёт автоматически!

Hastya

По моему половина сборщиков мусора как раз по этой причине с циклическими структурами не справляются. Если я не прав - поправьте.
Придется констатировать, что твои знания о сборщиках мусора полностью неверны. Как и об алгоритмах современных GC.
offtop: Интересно, откуда у людей стремление спорить на тему, в которой они совершенно не разбираются - и никогда GC не пользовались?

Dasar

> Это в теории? Или ты сам на практике такой JIT видел?
второй .net как раз этим и занимается

Marinavo_0507

если ты в теме, расскажи лучше, бывают ли гибридные GC?
такие, чтоб для обычных данных юзали нормальные алгоритмы, а для хендлов внешних ресурсов - с гарантией своевременного освобождения
хотя тут дело не в GC походу
это нужно данные флажками специальными помечать, на уровне системы типов или на уровне рантайма

myrka68

Придется констатировать, что твои знания о сборщиках мусора полностью неверны. Как и об алгоритмах современных GC.
о!
может тогда ты сможешь разрешить спор и ?
ну или хотя бы выскажи своё мнение

Hastya

Управление ресурсами не есть задача GC.
Проблема контроля ресурсов достаточно красиво решается в языках с синтаксическими структурами типа блоков (например, Smalltalk или, в искаженном виде - те же делегаты C#).

Dasar

какое отношение делегаты имеют к управлению ресурсами?

Marinavo_0507

поподробнее?
конструкция типа "блок" есть во всех функциональных языках - называется "closure"

Hastya

какое отношение делегаты имеют к управлению ресурсами?
Блоки, или функторы - одно из средств организации ресурсных "скобок". Еще модны сейчас всяческие AOP и т.п.

Hastya

поподробнее?
ну например в Java нет встроенных синтаксических средств типа функторов, там обычно придумывают такие штуки:
 public interface IO_operation {
public void execute(FileStream file) throws IOException;
}

Marinavo_0507

признайся, ты ведь тоже не читал про smart_ptr, особенно shared_ptr ?

Ivan8209

>> К которому из?
>> Я даже тебе цифирки поставил. Надеюсь, ты их прочитать сможешь.
>> Либо укажи сам. Если ты действительно разбираешься в теме, тебе это будет нетрудно.
> Нееет. Ты сам давай думай,
Значит, указать не можешь.
Слив засчитан.
---
"Аллах не ведёт людей неверных."

kokoc88

Значит, указать не можешь.
Указать-то я могу. Это ты прочитать не можешь.
Слив засчитан.
Да, ты прав. Слив тебе засчитан. Ещё один. В плюс к тому, что ты не умеешь программировать на своих ненасильных языках; ты ещё и не знаешь ничего про garbage collection, reference counting и простые языки типа Си++. С сегодняшнего дня можешь не писать в программинге, ибо то, что ты пишешь является полным маразмом, если это теория; и неработоспособным, если это практика.

Landstreicher

> второй .net как раз этим и занимается
Есть конкретные примеры, подтверждающие, что он действительно способен проводить такие оптимизации?
Что подразумевается под .NET? Компилятор C# от MS? Я уверен, что Mono не способно рюхать такие вещи.

Landstreicher

Думаю, что всякие shared_ptr не способны полностью решить проблему, которую описывает .
В таких ядерно-подобных программах имеется большое количество объектов типа "файл", "поток", "процесс", "сокет", которые ссылаются друг на друга. Например, логично в потоке иметь ссылку на процесс, а в процессе — ссылку на список открытых файловых дескрипторов. В свою очередь, в сокете логично хранить ссылку на поток, который будить, когда в сокет приходят данные. IMHO чем больше таких типов объектов и чем больше фич реализует система, тем больше вероятность образования циклов.
К сожалению, не знаю как это сделано в ядре (какой-нибудь крупной ОС). Может быть отцы расскажут?
Если ставить задачу уничтожения циклов, то imho нужно применять методы статического анализа. Например, вводим иерархию структур (или классов). При этом если A выше B по иерархии, то A может содержать ссылку на B, а B — не может содержать ссылку на A. При компиляции такие условия легко проверять.
Еще раз повторюсь, было бы интересно знать как эта проблема решается в ядрах ОС.

kokoc88

Например, логично в потоке иметь ссылку на процесс, а в процессе — ссылку на список открытых файловых дескрипторов. В свою очередь, в сокете логично хранить ссылку на поток, который будить, когда в сокет приходят данные. IMHO чем больше таких типов объектов и чем больше фич реализует система, тем больше вероятность образования циклов.
Пример неудачный. Ссылки на процессы, потоки и сокеты обычно хранят не в виде shared_ptr'ов. Когда в сокет приходят данные, и так выполняется поток, в котором он работает (по выходу из wait операции); либо поток на тред пуле.

Landstreicher

> Когда в сокет приходят данные, и так выполняется поток, в котором он работает
Что значит "и так"? Кто-то должен этот "и так" реализовывать, не с неба же он свалился.

Dasar

> Что подразумевается под .NET? Компилятор C# от MS? Я уверен, что Mono не способно рюхать такие вещи
в данном случае понимается именно JIT-компилятор.
на всякий случай напоминаю, что:
JIT-компилятор - это компилятор, который переводит il-код (byte-код) в маш. код.
а C#-компилятор - это компилятор, который переводит C# в il-код(byte-код)

kokoc88

> Когда в сокет приходят данные, и так выполняется поток, в котором он работает
Что значит "и так"? Кто-то должен этот "и так" реализовывать, не с неба же он свалился.
Значит "и так". Мы тут не говорим о том, на чём надо писать ОС. Это отдельная тема. Для прикладной программы тебе это обеспечивают.
Внутри ОС, наверное, есть иерархия. Ты никогда не читал "When a process terminates, OS also closes all unused file handles, sockets, and frees all resources, associated with the process"?

Landstreicher

> в данном случае понимается именно JIT-компилятор.
Ок, понял.
Все-таки, какие есть методы, позволяющие достоверно установить, что JIT-компилятор способен проводить такие оптимизации?

nikita270601

В моно есть ahead-of-time компилятор, можно посмотреть код, который он генерирует. А у MS не знаю, есть ли такие штуки.

Landstreicher

> Мы тут не говорим о том, на чём надо писать ОС.
> Это отдельная тема. Для прикладной программы тебе это обеспечивают.
Речь идет как раз о том, как писать ОС-подобные программы, в которых возникают такие проблемы.
Примеры таких приложений: apache, squid. Они работают в user-space, но в них приходится заводить структуры типа "поток", "процесс", "соединение" итп.
обсуждает возможность применения shared_ptr для решения таких задач.
Конкретный вопрос: "могут ли shared_ptr решить проблему учета ресурсов в приложениях типа apache/squid?".
PS. Неужели так сложно понять, о чем идет речь?

kokoc88

Речь идет как раз о том, как писать ОС-подобные программы, в которых возникают такие проблемы.
Примеры таких приложений: apache, squid. Они работают в user-space, но в них приходится заводить структуры типа "поток", "процесс", "соединение" итп.
Допустим. В апаче есть структура типа "соединение". И у неё всё в порядке с потоком, в котором она ждёт ответа от удалённого хоста. Её разбудят на произвольном потоке в тред пуле.
В логическом же смысле "типа поток" владеет своим соединением, как машина колёсами. Машина может менять колёса, а колёса машину обычно не меняют. Тут очень тяжело придумать вариант циклических ссылок. Ровно как и придумать пример использования shared_ptr.
"могут ли shared_ptr решить проблему учета ресурсов в приложениях типа apache/squid?".

С учётом ресурсов справляются деструкторы. Подсчёт ссылок в данном случае использовать не стоит.
PS. Неужели так сложно понять, о чем идет речь?

Неужели так сложно понять, что тебя поняли? И что пример неудачный.

Marinavo_0507

К сожалению, не знаю как это сделано в ядре (какой-нибудь крупной ОС). Может быть отцы расскажут?
Ссылки там считают Нужно просто быть аккуратным и не забывать это делать
Основные проблемы сейчас не в них, а в хитрых блокировках. То есть, например бывает, что ссылки все кончились, а освободить ресурс прямо сейчас нельзя, потому что мы не в том контексте.

Marinavo_0507

В squid, насколько я помню, ручной подсчёт ссылок. В недописанной заброшенной новой версии на плюсах - не знаю. Там есть разнообразные ресурсы: несколько типов сокетов и открытые файлы хранилища, состоящие между собой в непростых отношениях.
В apache исходников не видел, но вроде там и так всё просто, так как за сокет отвечает конкретный процесс или поток.

Marinavo_0507

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

kokoc88

Например, в проксе с одним сокетом может быть связан список клиентов, которым нужно раздавать приходящий из него контент. А у клиента, в свою очередь, ссылка на сервер, с которого приходит контент. Вот уже и цикл.
Ничего не понятно. Опиши поподробнее. Где в пределах одной программы клиент, сокет, и ссылка на сервер (на какой сервер)?

Landstreicher

> Ссылки там считают Нужно просто быть аккуратным и не забывать это делать
Как удается избежать циклических ссылок в ядре Linux? Есть какая-то иерархия объектов?
> Основные проблемы сейчас не в них, а в хитрых блокировках. То есть, например бывает, что ссылки > все кончились, а освободить ресурс прямо сейчас нельзя, потому что мы не в том контексте.
Не в том контексте — в смысле на другом процессоре, в другом потоке?
Не совсем понятно. Почему нельзя написать функцию освобождения ресурса, так чтобы она могла работать в любом контекстке?

Landstreicher

> С учётом ресурсов справляются деструкторы. Подсчёт ссылок в данном случае использовать не стоит.
Судя по твоим ответам, ты понимаешь еще хуже, чем я думал. Перевожу:
Основной вопрос стоит так — когда вызывать деструктор?
Для определения этого момента времени и предлагает использовать подсчет ссылок. Аргументов, показывающих, недостатки такого подхода ты пока не привел.

Marinavo_0507

Как удается избежать циклических ссылок в ядре Linux? Есть какая-то иерархия объектов?
Фиг его знает, я так глобально не мыслил.
Не в том контексте — в смысле на другом процессоре, в другом потоке?
Не совсем понятно. Почему нельзя написать функцию освобождения ресурса, так чтобы она могла работать в любом контекстке?
Ну например, в контексте прерывания. А чтобы освободить ресурс, нужно в аппаратный регистр записать, а с ними кто-то ещё работает, возможно на другом процессоре.

Marinavo_0507

Кеширующий HTTP-прокси, например squid.

kokoc88

Основной вопрос стоит так — когда вызывать деструктор?
Для определения этого момента времени и предлагает использовать подсчет ссылок. Аргументов, показывающих, недостатки такого подхода ты пока не привел.
Я тебе привёл аргументы того, что твой пример неудачный. В прикладных программах, которые ты привёл, видна чёткая цепь объектов, чёткая иерархия. В таком случае не используют подсчёт ссылок - достаточно, чтобы родительский объект освободил дочерние. Нужен пример, когда указатели на объект действительно нуждаются в подсчёте.

kokoc88

Кеширующий HTTP-прокси, например squid.
Я не знаю, как оно устроено. Напиши примерный список используемых структур для хранения ресурсов. Не ясно, что значит "несколько клиентов вешать на один сокет".

Landstreicher

> В прикладных программах, которые ты привёл, видна чёткая цепь объектов, чёткая иерархия.
Приведи пример такой иерархии для squid-а.

kokoc88

Приведи пример такой иерархии для squid-а.
Ну я не вижу разницы. Мне пока что не показали, как там всё устроено внутри. Поставь более чёткую задачу.

Dasar

> Например, в проксе с одним сокетом может быть связан список клиентов, которым нужно раздавать приходящий из него контент. А у клиента, в свою очередь, ссылка на сервер, с которого приходит контент. Вот уже и цикл.
это скорее weak_ptr, чем shared_ptr

Landstreicher

> Ну я не вижу разницы. Мне пока что не показали, как там всё устроено внутри. Поставь более чёткую задачу.
Тогда на каких основаниях ты решил, что там можно построить такую иерархию?

kokoc88

> Ну я не вижу разницы. Мне пока что не показали, как там всё устроено внутри. Поставь более чёткую задачу.
Тогда на каких основаниях ты решил, что там можно построить такую иерархию?
На основаниях своих соображений. Прокси серверу достаточно выделить одну структуру на каждого клиента. У неё можно считать ссылки или прикрутить к ней один объект синхронизации. Я не вижу здесь никаких указателей в обе стороны. И поэтому прошу написать, где видишь их ты?

Marinavo_0507

Если клиент отвалился, и других клиентов для того же объекта нет, то соединение с сервером (в зависимости от ситуации) уже не нужно, надо его закрыть, и поскорей, чтоб не качать лишнего. Но в некоторых ситуациях надо докачать объект в кеш. То есть, в каком-то виде ссылка от структуры "клиентский запрос" до структуры "соединение с сервером" должна присутствовать.

kokoc88

Если клиент отвалился, и других клиентов для того же объекта нет, то соединение с сервером (в зависимости от ситуации) уже не нужно, надо его закрыть, и поскорей, чтоб не качать лишнего. Но в некоторых ситуациях надо докачать объект в кеш. То есть, в каком-то виде ссылка от структуры "клиентский запрос" до структуры "соединение с сервером" должна присутствовать.
До сих пор не вижу циклических ссылок. Давай я напишу, как себе представляю задачу:

Клиент Прокси

connect -> [client data
send -> socket ->
send -> socket ->
send -> socket ->
send -> socket ->
]

sbs-66

Придется констатировать, что твои знания о сборщиках мусора полностью неверны. Как и об алгоритмах современных GC.offtop: Интересно, откуда у людей стремление спорить на тему, в которой они совершенно не разбираются - и никогда GC не пользовались?
Я нигде не утверждал, что я большой знаток GC. Я лишь говорю, что в C++ есть возможность тоже не заморачиваться ручным управлением памятью + возможность не заморачиваться управлением ресурсами + возможность очень эффективно работать с памятью, чего C# и Java не позволяют в принципе.
2 крёстныйотец
1. C неудобен так как не ООП, а ООП надо, чтобы код был хорошим и понятным и легко поддерживался. Писать сложниые алгоритмы с множеством связанных сущностей на С просто глупо.
2. Аллокации идут не обязательно подряд. Мы можем выделять много маленьких блоков памяти, часть из них освободить, потом выделить несколько больших блоков, освободить половину блоков и т.д. Всё это может приводить к фрагментации кучи. Обычные аллокаторы могут работать сильно медленнее самописных, заточенных под конкретную задачу. Банально, если мы заведём аллокатор для блоков фиксированного размера, то мы можем вообще не заботиться о фрагментации, выделяя и освобождая память в нужних местах. Ещё быстрее работает стековый аллокатор. А стандартная куча винды или рунтайм библиоткеки С будет работать плохо, так как она уневерсальна (и не очень хорошая).

Marinavo_0507

C неудобен так как не ООП, а ООП надо, чтобы код был хорошим и понятным и легко поддерживался. Писать сложниые алгоритмы с множеством связанных сущностей на С просто глупо.
фанатизм
Аллокации идут не обязательно подряд. Мы можем выделять много маленьких блоков памяти, часть из них освободить, потом выделить несколько больших блоков, освободить половину блоков и т.д. Всё это может приводить к фрагментации кучи.
А ты не освобождай ни часть, ни половину.
Освобождай всё в конце, как и собираешься. Только не низкоуровневым хаком, а штатным деаллокатором.

Ober

фанатизм
религия =)

What To Believe
Worry less about what to believe and more about why. Know where your "Style Rules" come from:

  • Religion, Good vs. Evil "This way is better."
  • Philosophy "This is consistent with other things."
  • Robustness, Liability, Safety, Ethics "I'll put in redundant checks to avoid something horrible."
  • Legality "Our lawyers say do it this way."
  • Personality, Opinion "I like it this way."
  • Compatibility "Another tool expects this way."
  • Portability "Other compilers prefer this way."
  • Cooperation, Convention "It has to be done some uniform way, so we agreed on this one."
  • Habit, Tradition "We've always done it this way."
  • Ability "My programmers aren't sophisticated enough."
  • Memory "Knowing how I would do it means I don't have to remember how I did do it."
  • Superstition "I'm scared to do it differently."
  • Practicality "This makes other things easier."

Ivan8209

> Мы можем выделять много маленьких блоков памяти, часть из них освободить,
> потом выделить несколько больших блоков, освободить половину блоков и т.д.
> Всё это может приводить к фрагментации кучи.
Этот вопрос решается даже в низкоуровневых языках, и ещё более успешно --- в высокоуровневых.
> Обычные аллокаторы могут работать сильно медленнее самописных, заточенных под конкретную задачу.
> Банально, если мы заведём аллокатор для блоков фиксированного размера, то мы можем
> вообще не заботиться о фрагментации, выделяя и освобождая память в нужних местах.
> Ещё быстрее работает стековый аллокатор.
Это всё особые случаи, которые слишком просты.
> А стандартная куча винды или рунтайм библиоткеки С будет работать плохо,
> так как она уневерсальна (и не очень хорошая).
Универсальность и качество --- разные вещи.
---
"Аллах не ведёт людей неверных."

sbs-66

Тут понимаешь в чём дело. Я когда пишу код не знаю, будет он достаточно быстрым или нет. И если я вижу под профайлером (или ещё как что память аллокируется неэффективно, то мне проже в одном месте поменять аллокатор, чем код переписать. Плюс это даёт большую гибкость. Если сущности имеют одинаковый размер, но их по ходу работы создаётся много, хотя в каждый момент их живёт ограниченное количество, то выгоднее использовать аллокатор для блоков одинакового размера, чем тупо не освобождать память. Плюс, если тупо не освобождать память, а аллокатор использовать стандартный, то будет не то же, чем специальный аллокатор и гроханье кучи в конце, а медленее.
Плюс тупо не освобождать память тоже нельзя, т.к. будет расти рабочее множество программы, из-за чего может возникнуть свопирование, что вызовет тормоза сильнее, чем мы ожидали устранить более эффективной аллокацией.
PS. Что касается C vs. С++, то непонятно, зачем использовать С, если он не даёт преимуществ перед С++, но большая часть программы написана на C++. Это же лишний геморой. НУ и плюс я действительно считаю, что с ООП удобнее, чем без. Готов даже эксперимент провести на какой-нибудь задаче нужной степени сложности.

apl13

In 2003, processors are a thousand times faster, memories are a thousand times larger, and disks are a factor of ten thousand larger, for roughly constant dollars.
Любая программа стремится занять всю доступную память.

kokoc88

До сих пор не вижу циклических ссылок. Давай я напишу, как себе представляю задачу:
Ага. Задачу я представил совсем не так, как надо. Одно соединение клиента обходится двумя сокетами. Где тут можно вставить циклическую ссылку - ума не приложу.
Edit: Хотя... Вроде бы всё-таки можно придумать некоторый механизм для одного сокета для клиента и нескольких запросов на сервер. Типа прокси танцует с клиентом с persistent connection, а запросы на сервер отсылает по очереди. Хотя в этом случае всё равно придётся выстраивать запросы в чёткую очередь, и выигрыш довольно сомнителен. Если вообще есть.

Landstreicher

> фанатизм
+1
Вычислительные алгоритмы прекрасно пишутся на С.

Sebasten

Гораздо интереснее было бы читать тред, если каждый, высказывающий своё мнение о том на чём и как надо всё делать в начале указывал занимаемую им должность и приблизительный оклад
Есть кто-нибудь, кого действительно заботит коммерческая выгода проекта или все мечтают о будущем?
Про статью: мне показалась тупняком и спекуляцией.

Ivan8209

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

sbs-66

Они и на ассемблере пишуться прекрасно. Вопрос зачем?

bleyman

О, как прекрасно флуд пошёл!
> RS-232 поверх TCP --- круче, наверное, только "electricity over IP".
Вот ты ленивый, а?
http://www.google.com/search?q=rs232%20over%20tcp%2Dip
Судя по количеству результатов - задача не просто частая, а очень частая. Догадаешься, почему?
> Предлагаю не сравнивать возможности по написанию драйверов, это такая область,
Ну почему обязательно драйвера? Видишь ли, "областей" в программировании вообще не так уж и много, я просто привёл наиболее характерный пример манипулирования низкоуровневой информацией, с которым лучше плюсов вообще ничего, по-моему, не справляется.
> где лучше всего может оказаться ассемблер.
> С этой точки зрения, ассемблер, в связке с M4, ничем не хуже.
Контроль за типизацией и оптимизация.
> Рассматриваем типичных насильников, извращенцев, вынужденных писать на сях, в расчёт не берём.
Вот ты и споришь с mike, а думаешь, что споришь с "типичным насильником".
>> Если GC не успеет собрать мусор до того момента, как я попытаюсь открыть файл снова, случатся оппаньки.
>Какие и почему?
Access Violation - файл уже открыт для записи и, соответственно, залочен на уровне оси. Что очень правильно. Теоретически ось могла бы попытаться узнать у той проги, которая его открыла для записи, нужен ли он ей ещё, та прога спросит у своего GC и всё станет хорошо, но на практике так не бывает.
Ну так что, расскажешь про "хорошие GC", которые избавляют от необходимости руками сигнализировать о необходимости отпустить ресурс?
2Godfather: не, я могу и на С писать SomeDataConverter_Convert(SomeDataConverterParams * this, SomeData * source, SomeOtherData * result но зачем? Да, наследование и полиморфизм в таких задачах не нужны, но плюсы дают возможность логичной и очевидной группировки методов друг с другом и с данными, причём ещё и отлавливают ошибки, и избавляют от необходимости писать дополнительные символы при обращении к "близкому" методу.
2 et al, по поводу коммерческого софта на плюсах: вы забываете один крайне важный фактор - коммерческий софт пишется в основном под винду, которая сама написана на С/С++. В результате программер, сталкивающийся с задачами от "заставить кнопку мигнуть три раза" до "отследить изменение содержимого директории" вначале ставит МСДН, потом Platform SDK, а потом начинает писать на плюсах.
2&Darkgray: умеет ли делать компилятор такую оптимизацию - неизвестно, но точно может начать уметь. В любом случае, дядки из M$ предлагают использовать клёвую штуку AppDomain, которая даёт эффект отдельного процесса, но без всякого оверхеда (поскольку за счёт манагнутости реализуется в том же адресном пространстве). И вот их можно выгружать.

Ivan8209

>> RS-232 поверх TCP --- круче, наверное, только "electricity over IP".
> Вот ты ленивый, а?
> http://www.google.com/search?q=rs232%20over%20tcp%2Dip
Мда-а-а.
>> Предлагаю не сравнивать возможности по написанию драйверов, это такая область,
> Ну почему обязательно драйвера? Видишь ли, "областей" в программировании вообще
> не так уж и много, я просто привёл наиболее характерный пример манипулирования
> низкоуровневой информацией, с которым лучше плюсов вообще ничего, по-моему, не справляется.
Есть просто си, которые справляются ничуть не хуже, а то и даже лучше.
>> где лучше всего может оказаться ассемблер.
>> С этой точки зрения, ассемблер, в связке с M4, ничем не хуже.
> Контроль за типизацией и оптимизация.
И именно за счёт более слабой типизации.
>> Рассматриваем типичных насильников, извращенцев, вынужденных писать на сях, в расчёт не берём.
> Вот ты и споришь с mike, а думаешь, что споришь с "типичным насильником".
Типичный насильник ещё тупее?
Или наоборот?
>>> Если GC не успеет собрать мусор до того момента, как я попытаюсь открыть файл снова, случатся оппаньки.
>> Какие и почему?
> Access Violation - файл уже открыт для записи и, соответственно, залочен на уровне оси.
> Что очень правильно. Теоретически ось могла бы попытаться узнать у той проги, которая
> его открыла для записи, нужен ли он ей ещё, та прога спросит у своего GC и всё станет
> хорошо, но на практике так не бывает.
> Ну так что, расскажешь про "хорошие GC", которые избавляют от необходимости руками
> сигнализировать о необходимости отпустить ресурс?
Хочешь сказать, что это не одноразовая работа?
Кроме того, в том виде, в котором задачу ставишь ты, это в общем случае невозможно.
Что если той, другой задаче файл ещё нужен? Практически, всё, что требуется,
это подпилить открытие файла, чтобы оно "try open-file throw recover collect-garbage open-file throw endtry".
Обёртка, кстати, довольно общая, поэтому можно написать макрос и пихать его, куда ни попадя.
Почти.
---
"Аллах не ведёт людей неверных."

Marinavo_0507

Задачу я представил совсем не так, как надо. Одно соединение клиента обходится двумя сокетами. Где тут можно вставить циклическую ссылку - ума не приложу.
Тут дело в том, что несколько клиентов могут одновременно захотеть один, грубо говоря, URL, и тогда они разделяют соединение с сервером (через посредство файла в кеше, а может, и без него) Тут надо учитывать, что клиенты качают на разной скорости, и нельзя задерживать быстрых из-за того, что медленные ещё не получили свой кусок, поэтому обычно это складывается в файл с той скоростью, с какой отдаёт сервер, медленные клиенты читают из разных позиций файла, быстрые клиенты получают сразу после прихода от сервера. Быстрый клиент переводится в медленные, если накапливается слишком большой буфер неотправленных данных. Если ни одного быстрого клиента не осталось, большой буфер отменяется.
То есть, клиентские сокеты и соединения с сервером - напрямую не связаны, но находятся в отношении N-(0,1 которое меняется со временем.
При этом и соединение с сервером должно узнавать, если вдруг кончатся все клиенты, и клиентский запрос должен получать сообщение, если сервер неожиданно закроет соединение, причём немедленно.

bleyman

> Мда-а-а.
Что "мда-а-а"? Ты реально не понимаешь, зачем это нужно, причём настолько часто? Фи, пустышка...
> Есть просто си, которые справляются ничуть не хуже, а то и даже лучше.
Исчо раз повторяю - никто не заставляет писать семнадцать уровней абстракции. Объекты как способ группировать процедуры и данные, темплейты как способ реализовывать высокоуровневые штуковины, но без фанатизма.
> И именно за счёт более слабой типизации.
Если ты в каком-нибудь жаваскрипте попытаешься вызвать несуществующий метод, то словишь эксепшен. Если ты в ассемблере промахнёшься со структурой, параметрами или вообще чем угодно, то словишь опять-таки что угодно. Ладно, давай оставим эту тему, её серьёзно обсуждать невозможно =)
> Типичный насильник ещё тупее?
Судя по тому, что у майка нет мемори ликов (с его слов всё немножко сложнее =)
> Хочешь сказать, что это не одноразовая работа?
Хочу сказать, что твои слова про "хороший GC", который якобы решает какие-то ещё проблемы, кроме утечек памяти/зависших ссылок, есть пиздёж. Я не прав?
Кстати, вызов GC.Collect есть грубый хак и вмешательство в нормальную его работу, так делать нельзя.

Marinavo_0507

темплейты как способ реализовывать высокоуровневые штуковины
слабоваты они в отсутствии closures
вот если C# взять со всеми обещанными наворотами, то там ещё можно что-то высокоуровневое сделать

sbs-66

Для контейнеров в самый раз, а больше они мало для чего нужны, эти шаблоны...

Ivan8209

>> Мда-а-а.
> Что "мда-а-а"? Ты реально не понимаешь, зачем это нужно, причём настолько часто?
Просто не ожидал от тебя такого.
>> Есть просто си, которые справляются ничуть не хуже, а то и даже лучше.
> Исчо раз повторяю - никто не заставляет писать семнадцать уровней абстракции.
> Объекты как способ группировать процедуры и данные, темплейты как способ
> реализовывать высокоуровневые штуковины, но без фанатизма.
То есть использовать из плюсов возможностей ровно на модульность и макропроцессор.
>> И именно за счёт более слабой типизации.
> Если ты в каком-нибудь жаваскрипте попытаешься вызвать несуществующий метод, то словишь эксепшен.
> Если ты в ассемблере промахнёшься со структурой, параметрами или вообще чем угодно, то словишь опять-таки что угодно.
Ну, нас тут учат, что если работать "правильно", то "что угодно" не словишь.
Кроме того, есть куча способов, как писать так правильно, чтобы не словить.
> Ладно, давай оставим эту тему, её серьёзно обсуждать невозможно =)
Это да.
>> Хочешь сказать, что это не одноразовая работа?
> Хочу сказать, что твои слова про "хороший GC", который якобы решает какие-то ещё проблемы,
> кроме утечек памяти/зависших ссылок, есть пиздёж. Я не прав?
Почему?
У тебя есть, в некотором смысле, куча из файловых дескрипторов.
Ничто не мешает СМ знать об этом и закрывать более не используемые файлы или сокеты.
Кстати, твоя задача о запертом файле как раз этого рода, можно раз и навсегда научиться
выделять ресурсы так, чтобы вовремя отпирать запертые, но забытые.
> Кстати, вызов GC.Collect есть грубый хак и вмешательство в нормальную его работу, так делать нельзя.
Так делать можно и нужно, вопрос только когда.
---
"Аллах не ведёт людей неверных."

garikus

>> Если GC не успеет собрать мусор до того момента, как я попытаюсь открыть файл снова, случатся оппаньки.
>Какие и почему?
Access Violation - файл уже открыт для записи и, соответственно, залочен на уровне оси. Что очень правильно. Теоретически ось могла бы попытаться узнать у той проги, которая его открыла для записи, нужен ли он ей ещё, та прога спросит у своего GC и всё станет хорошо, но на практике так не бывает.
Ну так что, расскажешь про "хорошие GC", которые избавляют от необходимости руками сигнализировать о необходимости отпустить ресурс?
Если сработает FINALIZE, и файл был открыт, то он закроется. Но кто мешает закрыть файл до сборки мусора?

Marinavo_0507

не, я могу и на С писать SomeDataConverter_Convert(SomeDataConverterParams * this, SomeData * source, SomeOtherData * result но зачем? Да, наследование и полиморфизм в таких задачах не нужны, но плюсы дают возможность логичной и очевидной группировки методов друг с другом и с данными, причём ещё и отлавливают ошибки, и избавляют от необходимости писать дополнительные символы при обращении к "близкому" методу.
Не понятно, что за логичная группировка
Ты привяжешь конвертацию к источнику, к результату, или к параметру?
На мой взгляд, как раз ситуация, когда C++-style ООП сосёт.

Ivan8209

> Но кто мешает закрыть файл до сборки мусора?
А зачем это делать вручную, если это можно спихнуть другому?
Тем более, что этому другому делать надо значительно меньше, чем тебе:
"open-file" --- одно на всех, а используется может много где.
---
"Аллах не ведёт людей неверных."

garikus

> Но кто мешает закрыть файл до сборки мусора?
А зачем это делать вручную, если это можно спихнуть другому?
Тем более, что этому другому делать надо значительно меньше, чем тебе:
"open-file" --- одно на всех, а используется может много где.
Если файл нужен только этой программе, то не нужно.

Marinavo_0507

Для контейнеров в самый раз, а больше они мало для чего нужны, эти шаблоны...
Для контейнеров в нормальных языках есть более простые средства.
А от такой сложной фигни, как шаблоны, можно было бы большего ожидать.
Например, был случай, когда надо было обходить точки на плоскости в разном порядке. Иногда сначала по x, потом по y, иногда наоборот, ну и в разных направлениях тоже.
Внутри - сложный блок кода.
В результате я сделал на макросах. Это было коротко и не так уж непонятно, но сильно некрасиво.
На самом деле в гнутых расширениях C сейчас есть почти-closures, можно сделать на них, будет почти как на нормальном языке.

Dasar

> Например, был случай, когда надо было обходить точки на плоскости в разном порядке. Иногда сначала по x, потом по y, иногда наоборот, ну и в разных направлениях тоже.
Внутри - сложный блок кода.
из шаблонов нормальные же closure получаются. особенно если учесть, что шаблоны очень хорошо inline-ятся.
данная задачка решается как-то так:


void Walk<Way>
{
int x = 0;
int y = 0;
while(Way::Next(x, y
{
Do;
}
}
void main
{
Walk<XY_Way>
Walk<YX_Way>
}

class XY_Way
{
public: static bool Next(int& x, int& y)
{
++y;
if (y >= maxy)
{
++x;
y = 0;
if (x >= maxx)
return false;
}
return true;
}
};
class YX_Way
{
public: static bool Next(int& x, int& y)
{
++x;
if (x >= maxx)
{
++y;
x = 0;
if (y >= maxy)
return false;
}
return true;
}
};

Hastya

признайся, ты ведь тоже не читал про smart_ptr, особенно shared_ptr ?
признаюсь - smart_ptr я пользовался, когда писал на C++. Всех проблем они не решают - причем возникает новый класс проблем, когда обычные указатели приходится сочетать с "умными".

kokoc88

Тут дело в том, что несколько клиентов могут одновременно захотеть один, грубо говоря, URL, и тогда они разделяют соединение с сервером (через посредство файла в кеше, а может, и без него) Тут надо учитывать, что клиенты качают на разной скорости, и нельзя задерживать быстрых из-за того, что медленные ещё не получили свой кусок, поэтому обычно это складывается в файл с той скоростью, с какой отдаёт сервер, медленные клиенты читают из разных позиций файла, быстрые клиенты получают сразу после прихода от сервера. Быстрый клиент переводится в медленные, если накапливается слишком большой буфер неотправленных данных. Если ни одного быстрого клиента не осталось, большой буфер отменяется.
То есть, клиентские сокеты и соединения с сервером - напрямую не связаны, но находятся в отношении N-(0,1 которое меняется со временем.
При этом и соединение с сервером должно узнавать, если вдруг кончатся все клиенты, и клиентский запрос должен получать сообщение, если сервер неожиданно закроет соединение, причём немедленно.
Ты слишком усложнил простую задачу. Файловый кэш можно разделять, но работу с одним файлом лучше сделать через разые дескрипторы. Один URL разделять между клиентами у тебя вряд ли получится: они должны будут одновременно послать абсолютно идентичные запросы. Реализовывать частичное чтение из файла или полную буферизацию будет намного более накладно по ресурсам, чем применение различных соединений для двух клиентов. Учитывая, что почти все ОС поддерживают быстрые thread pool + io completion, реальную выгоду от применения описанных тобой методов можно получить только тогда, когда тясячи клиентов в первый раз делают запрос на один URL, причём одновременно. Не слишком-то хороший бонус для удесятирённой сложности программы.
Мне кажется, что предложенное тобой решение - архитектурно неверно. Мало того, тема отталкивалась от GC, который в данном случае ничем не поможет: программа получится такая же сложная с соответствующим количеством проблем.

Marinavo_0507

не хочу так, это очень длинно и непонятно
двойной for понятнее, а специальный хитрый инкремент отвлекает от сути задачи
а Do в моём случае доступался к огромной куче локальных переменных, в твоём способе надо было бы их переносить в поля специального класса - то есть закат солнца вручную
а вот посмотрел я код, наврал я
макросы немного для другой задачи, тоже похожей, там надо было потом для каждой такой точки в разном порядке обрабатывать соседей
а обход удалось сделать всегда сначала по x, потом по y

Marinavo_0507

Один URL разделять между клиентами у тебя вряд ли получится: они должны будут одновременно послать абсолютно идентичные запросы.
Я реальную ситуацию рассказываю, как сделано.
Идентичные запросы получаются, например, если ссылка опубликована на популярном форуме.

Marinavo_0507

Всех проблем они не решают - причем возникает новый класс проблем, когда обычные указатели приходится сочетать с "умными".
Ну так расскажи плиз.
А то я только теоретически могу догадываться о проблемах.

Dasar

> а Do в моём случае доступался к огромной куче локальных переменных, в твоём способе надо было бы их переносить в поля специального класса - то есть закат солнца вручную
зачем? убери Do. и напиши туда свой код, который имеет доступ к куче локальных переменных.
> макросы немного для другой задачи, тоже похожей, там надо было потом для каждой такой точки в разном порядке обрабатывать соседей
все тоже самое:

for(Neighbors::iterator it = Neighbors::begin; it != Neighbors::end; ++it)
{
}

Hastya

А то я только теоретически могу догадываться о проблемах.
Тот же WinAPI может тебе вернуть кучу указателей неизвестного размера и с неопределенными временем жизни. Следить за ними надо отдельно, причем очень внимательно вчитываться в документацию, не дай боже чего пропустить.

Dasar

> макросы немного для другой задачи, тоже похожей, там надо было потом для каждой такой точки в разном порядке обрабатывать соседей
основное утверждение выглядит так:
код на макросах - один в один переписывается на шаблонах
вывод: ты не умеешь писать код на шаблонах

kokoc88

Я реальную ситуацию рассказываю, как сделано.
Идентичные запросы получаются, например, если ссылка опубликована на популярном форуме.
Я уже написал в своём посте: твоё решение пригодно, когда тысячи одновременно в первый раз кликнут на эту ссылку. Потом она сохранится в кэше. Архитектурно неверно. Сложно. Явно не подразумевает подсчёт ссылок. Не показывает, чем лучше GC (уж с таким-то количеством всевозможных дескрипторов с ума сойдёшь контролировать освобождение ресурсов).

bleyman

Тот же WinAPI может тебе вернуть кучу указателей неизвестного размера и с неопределенными временем жизни.
эммм. Тот же винапи крайне редко возвращает указатели именно потому, что если тебе их придётся освобождать через винапи же. Я что-то даже не припомню, когда оно такое делает.

kokoc88

эммм. Тот же винапи крайне редко возвращает указатели именно потому, что если тебе их придётся освобождать через винапи же. Я что-то даже не припомню, когда оно такое делает.
Под указателями он мог понимать всяческие хэндлы, или BSTR, или COM память...

Marinavo_0507

объявлять итераторы сложнее, чем

let way1 f = loop 0 nx (fun x -> loop 0 ny (fun y -> f x y
and way2 f = loop 0 ny (fun y -> loop 0 nx (fun x -> f x y
in
let our_way = if /* условие */ then way1 else way2 in
our_way (fun x y ->
/* тут сложный код */
)

код короче, и порядок совпадает с тем, в каком я об этом думаю
если захочется, можно избавиться от всех имён:

( if /* условие */ then
fun f -> loop 0 nx (fun x -> loop 0 ny (fun y -> f x y
else
fun f -> loop 0 ny (fun y -> loop 0 nx (fun x -> f x y
) ( fun x y ->
/* тут сложный код */
)

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

Hastya

Под указателями он мог понимать всяческие хэндлы, или BSTR, или COM память...
Да.
VOID WINAPI * PFN_HSE_IO_COMPLETION_CALLBACK(
LPEXTENSION_CONTROL_BLOCK lpECB,
PVOID pContext,
DWORD cbIO,
DWORD dwError
);

Parameters

lpECB

Points to the EXTENSION_CONTROL_BLOCK data structure that is associated with the current, active request.

pContext

Points to an application-defined context that was supplied to IIS when the asynchronous I/O callback function was registered.

cbIO

A DWORD that contains the number of bytes of I/O in the last call.

dwError

The error code returned.

Вопрос на засыпку - кто и как освобождает указатель pContext, если он передан?

Marinavo_0507

основное утверждение выглядит так:
код на макросах - один в один переписывается на шаблонах
разве можно часть функции, даже не полный блок, а скажем заголовок цикла, объявить шаблоном?
типа аналог

#define START_XY for (x=0; x<=N; x++) for (y=0; y<=N; y++)
#define START_YX for (y=0; y<=N; y++) for (x=0; x<=N; x++)

// ....

#define COMPLEX_CODE_1 do { /* тут много */} while(0)
if (cond1) {
START_XY COMPLEX_CODE_1;
} else {
START_YX COMPLEX_CODE_1;
}
#undef COMPLEX_CODE_1

// ...
#define COMPLEX_CODE_2 do { /* тут много */} while(0)
if (cond2) {
START_XY COMPLEX_CODE_2;
} else {
START_YX COMPLEX_CODE_2;
}
#undef COMPLEX_CODE_2

На хороших языках это красивее делается, и больше ситуаций, где это применимо.
А на шаблонах я писать и правда не умею - там простые вещи делаются сложно (кроме контейнеров, которые делаются просто, в то время как на хороших языках - делать не надо вообще ничего ) Зачем мне это изучать, если меня никто не заставляет?

Marinavo_0507

Я уже написал в своём посте: твоё решение пригодно, когда тысячи одновременно в первый раз кликнут на эту ссылку.
Ты меня убеждаешь, что эту задачу вообще не надо было решать, потому что она слишком сложна для C++? Ну а люди так сделали на C, и даже работает.
Сейчас веб-кеши не актуальны. Актуальны кеши торрентов.
Там вполне реально, что куча народу качает один и тот же файл, который на кеше ещё есть не польностью.

sbs-66

Делается это так.
class CDoSomething {
public:
CDoSomething {}

//....

void Do( //... );

private:
void step( x, y, //... );

};

CDoSomething::Do( //... )
{
// условия циклов по x и y могут быть сколь угодно сложными,
// возможно потребуется написать ещё один метод для их проверки/итерирования
if( //*условие*// ) {
for( int x = 0; x < ?; x++ ) {
for( int y = 0; y < ?; y++ ) {
step( x, y, //... );
}
}
} else {
for( int y = 0; y < ?; y++ ) {
for( int x = 0; x < ?; x++ ) {
step( x, y, //... );
}
}
}
}

CDoSomething::step( x, y, //... )
{
// тут сложный код
}

Выглядит посложнее, чем то, что написал ты, но на практике я думаю окажется удобнее и идеологически правильнее. Класс скорее всего заводить не придётся, т.к. данные действия выполняются в рамках какого-то механизма (алгоритма который как раз и будет представлен классом. Просто часть кода будет выделена в отдельный метод, что полезно, ибо эта часть кода обособлена. С точки зрения понимания это гораздо понятнее шаблонов, которые тут не нужны, и уж тем более макросов.

Landstreicher

> код на макросах - один в один переписывается на шаблонах
Только в очень небольших узких случаях.
Вот, например, перепиши на шаблонах такой код (взято из реальной программы):

#define FUNCLASS(type,fun,pars) \
struct fun##Class: public BaseClass { \
type result; \
fun##ArgStruct funargs; \
virtual void do_work { \
/* порезано */
} \
virtual const char* name const { return #fun; } \
virtual int class_id const { return TypeClassId<fun##Class>::class_id; } \
};

пример использования
FUNCLASS(double, myfunc, (int n

Marinavo_0507

Выглядит посложнее, чем то, что написал ты, но на практике я думаю окажется удобнее и идеологически правильнее.
Сложнее, и сложный код вынесен в отдельную функцию, что означает, что надо заботиться о передачи ей локальных переменных, то есть их тоже засовывать в класс. Метод step нельзя встроить внутрь кода, а обязательно оформлять отдельно.
Идеологически правильно - только в случае победы идеологии ООП (в дурном понимании, как это принято в C++) над удобством и простотой, что ты и продемонстрировал,

kokoc88

Ты меня убеждаешь, что эту задачу вообще не надо было решать, потому что она слишком сложна для C++? Ну а люди так сделали на C, и даже работает.
Нет, я говорю что эту задачу вообще не стоило решать. Ни на каком языке. Бессмысленна на практике. (Мне жаль тех, кто сделал это на Си.) Плюс ко всему, я говорю, что языки с GC тут никак не помогли бы. И не видно чёткой необходимости использовать подсчёт ссылок.
Сейчас веб-кеши не актуальны. Актуальны кеши торрентов.
Там вполне реально, что куча народу качает один и тот же файл, который на кеше ещё есть не польностью.
Этот файл разбивается на части. Части, доступные клиентам, есть в кэше полностью. Опять же, здесь задача проста - работа только с файлами. Как я написал выше для кэша прокси, здесь проще всего использовать несколько файловых дескрипторов. Видимо, с какой-то буферизацией, которую лучше возложить на OS. Не вижу применения подсчёту ссылок.

Marinavo_0507

Этот файл разбивается на части. Части, доступные клиентам, есть в кэше полностью.
Типа не полностью скачанную часть зажать, не давать клиентам? Это неэффективно - зачем они ждать будут?
В любом случае, если все клиенты отвалились, всё равно нужно (если осталось ещё много) отменить закачку других частей, то есть зашатдаунить соединения с сидами.
Как я написал выше для кэша прокси, здесь проще всего использовать несколько файловых дескрипторов.
Даже если файловых дескрипторов несколько, клиентов нужно оповещать, что доступны следующие куски.

sbs-66

Я думаю, что в моём коде стороннему человеку будет проще разобраться, так что победа идеологии ООП окажется в итоге полезна.

Marinavo_0507

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

kokoc88

Типа не полностью скачанную часть зажать, не давать клиентам? Это неэффективно - зачем они ждать будут?
В любом случае, если все клиенты отвалились, всё равно нужно (если осталось ещё много) отменить закачку других частей, то есть зашатдаунить соединения с сидами.
Части, насколько я помню, довольно маленькие. По сравнению с общим объёмом файлов, распространяемых через торренты. Мало того, по соображениям безопасности не стоит отдавать недокачанные части клиентам. Там проверяются контрольные суммы, и т.п. Поэтому всё достаточно эффективно.
Зачем торрент-кэшам шатдаунить соединения с сидами? Файл надо кэшировать до конца, пока эти самые сиды есть. Впрочем, разговор опять не по теме. Свалились на рассмотрение каких-то глобальных задач, которые можно решать разными способами. На изначальный вопрос ответа так и не получено: пример, в котором без кольцевых ссылок не обойтись, не найден.
Даже если файловых дескрипторов несколько, клиентов нужно оповещать, что доступны следующие куски.
И как это противоречит всему, сказанному мной? И откуда здесь можно сделать вывод о наличии кольцевых ссылок?

Marinavo_0507

Части, насколько я помню, довольно маленькие. По сравнению с общим объёмом файлов, распространяемых через торренты.
Это не значит, что клиент, соединившийся с прокси, должен ждать, пока туда скачается полный блок. Что скажут пользователи? "У провайдера X торренты сразу начинают качаться, а у его конкурента Y - надо иногда по полчаса ждать". Сиды ведь бывают довольно тормозные.
Мало того, по соображениям безопасности не стоит отдавать недокачанные части клиентам. Там проверяются контрольные суммы, и т.п.
Контрольные суммы проверит клиент в любом случае, так что безопасность не у дел.
И как это противоречит всему, сказанному мной? И откуда здесь можно сделать вывод о наличии кольцевых ссылок?
Ладно, проехали. Если кольцевых ссылок не бывает, да и вообще считать их для внешних ресурсов не надо, хватает древовидных структур (на владеющих хранилищах мне даже приятнее

kokoc88

Это не значит, что клиент, соединившийся с прокси, должен ждать, пока туда скачается полный блок. Что скажут пользователи? "У провайдера X торренты сразу начинают качаться, а у его конкурента Y - надо иногда по полчаса ждать". Сиды ведь бывают довольно тормозные.
Ничего не скажут. Довольно тормозные сиды в любом случае будут долго раздавать.
Ладно, проехали. Если кольцевых ссылок не бывает, да и вообще считать их для внешних ресурсов не надо, хватает древовидных структур (на владеющих хранилищах мне даже приятнее
Они бывают. Надо просто попроще задачи ставить. Так, чтобы было очевидно, что неизбежно использование таких ссылок; и было видно, как тебе помогают в этом случае языки с GC. Т.е. как минимум в задаче не должна идти речь об огромном количестве захватываемых ресурсов, кроме памяти...

Marinavo_0507

Ничего не скажут. Довольно тормозные сиды в любом случае будут долго раздавать.
Лично мне приятно, если качаться начинает сразу, пусть и 100байт/с, чем ждать полчаса непонятно чего.
"Обратная связь" называется, слышал про такое?

kokoc88

Лично мне приятно, если качаться начинает сразу, пусть и 100байт/с, чем ждать полчаса непонятно чего.
"Обратная связь" называется, слышал про такое?
Да, а ждать, пока вообще появится хоть один сидер тебе приятно? Не говори ерунды, на общую скорость распространения торрентов подобные технические мелочи не влияют. Разговор опять ушёл от темы.

SPARTAK3959

Пример неизбежности циклических ссылок - игра Космические Рейнджеры 2. Там есть объект звезда, который хранит список всех кораблей и у каждого корабля есть указатель на звезду, в системе которой он находится. Когда происходит расчет хода (или когда игрок обращается к кораблю то корабль по указателю на звезду находит все остальные корабли в системе и вычисляет в зависимости от этого свое поведение. То же самое с созвездиями - объект созвездие содержит список звезд, у каждой звезды есть указатель на созвездие. Таким образом по звезде можно узнать созвездие и найти все соседние созведия, когда на планетах предлагают купить галакарту, а в созвездии узнать все звезды, когда нужно построить базу в случайной системе в полностью освобожденном созвездии. Так же для AI кораблей им нужно хранить в полях указатели на корабли, с которыми они имели дело на предыдущем ходу (кого они сейчас атакуют и от кого сматываются) и эти ссылки частенько бывают циклическими (корабли атакуют друг друга). Из-за всего этого деструкторы объектов весьма сложны и разработчики до сих пор не могут их написать правильно - люди не раз сталкивались с вылетами из игры при уничтожении кораблей.

Papazyan

Вот поэтому garbage collectors рулят.

kokoc88

Пример неизбежности циклических ссылок - игра Космические Рейнджеры 2.
Примером неизбежности циклических ссылок никогда не может быть какой-то программный продукт в целом. Надо приводить локальные задачи. Их очень мало, потому что почти всегда можно отказаться от ссылок в обе стороны. У меня даже самые бездумные реализации КР2 никак не стыкуются с необходимостью делать циклические ссылки.
то корабль по указателю на звезду находит все остальные корабли в системе и вычисляет в зависимости от этого свое поведение
А почему именно так? Почему бы некоторому контроллеру не вычислять поведение всех объектов в пределах одной звезды? Этот контроллер либо оперирует этими объектами сам; либо запрашивет решения непосредственно от этих объектов, передавая ссылку на хранилище объектов внутрь функции принятия решения.
То же самое с созвездиями - объект созвездие содержит список звезд, у каждой звезды есть указатель на созвездие.
Созвездие в КР2 вообще не нужно делать объектом, а скорее свойством звезды. Остальное кладётся в граф.
ак же для AI кораблей им нужно хранить в полях указатели на корабли, с которыми они имели дело на предыдущем ходу (кого они сейчас атакуют и от кого сматываются) и эти ссылки частенько бывают циклическими (корабли атакуют друг друга).
При взаимодействии через третье лицо, как я описал выше, необходимости в циклических ссылках не будет.

kokoc88

Из-за всего этого деструкторы объектов весьма сложны и разработчики до сих пор не могут их написать правильно - люди не раз сталкивались с вылетами из игры при уничтожении кораблей.
Кстати, даже при наличии всех описанных выше циклических ссылок между объектами, программу можно было написать так, чтобы она от этого и не падала, и не имела утечек. Плясать от идентификаторов.

Dasar


template<TResultType, TArgStruct>
struct FunClass
{
TResultType result;
TArgStruct funargs;
virtual void do_work{}
virtual const char* name const { return typeid(FunClass).name; }
virtual int class_id const { return TypeClassId<FunClass>::class_id; }
};

FunClass<double, DoubleArgs>

bastii

Циклические ссылки очень часто возникают. Например в ГУИ, есть контейнер с элементами-контролами, которые ссылаются на контейнер. Плюс подписка обработчиков на события. В итоге довольно не тривиальная структура с циклическими ссылками, которая заставляет напрягаться и придерживаться определенного протокола при удалении такой структуры. Не знаю, но меня лично напрягало это довольно сильно, когда приходилось разрабатывать свои структуры на СОМ, и ATL со своими смарт поинторами, конечно делали код чище, но в этой проблеме не помогали. И от общих усилий, затрачиваемых на проектирование и кодирование, это все занимало существенную часть.
С GC таких проблем нет. Что позволяет довольно легко разрабатывать сложные структуры, где много сущностей взаимодействую не тривиальным образом. В итоге вообще нет этого тормоза в применении идей ООП на практике.
В результате под GC среды (имею в виду Java и .NET существует много функциональных и гибких библиотек, каких, например, нет для С++/COM/ATL.
В качестве эксперимента предлагаю взять одну из библиотек из GC среды и переделать под C++ с подсчетом ссылок. Причем взять лучше что-нибудь современное, что от начала и до конца разрабатывалось под .NET — предлагаю WPF. Уверен, что если что-то и получиться, то это будет абсолютно не юзабельным для пользователя библиотеки.
А мощный язык, это конечно хорошо, но он не заменит развитую библиотеку, с большим числом готовых расширений от различных производителей, что например, сегодня существует для ASP.NET.

Ivan8209

> Почему бы некоторому контроллеру не вычислять
> поведение всех объектов в пределах одной звезды?
Потому что этот "контроллер" является неочевидной и,
вообще говоря, излишней сущностью, которая является
затычкой к случаю, из-за отсутствия автоматического
управления памятью.
> Созвездие в КР2 вообще не нужно делать объектом,
> а скорее свойством звезды.
Это такая разновидность "объектноориентированности",
когда сущность, являющуюся самостоятельным объектом,
понижают в ранге и вообще объявляют свойством.
> При взаимодействии через третье лицо, как я описал выше,
> необходимости в циклических ссылках не будет.
То есть, для того, чтобы избежать циклических ссылок, вместо
приличных средств управления памятью, которые надо сделать
один раз и навсегда, надо каждый раз изобретать третьи лица.
Вместо общего решения каждый раз изобретать костыль к случаю.
---
"Аллах не ведёт людей неверных."

Papazyan

Вместо общего решения каждый раз изобретать костыль к случаю.
Да, С++ники такие. Сегодня по приколу зашел в С++ раздел на rsdn и увидел замечательную тему про "свободный" интерфейс. Суть этой модной технологии сводится к проганью структур с данными + функций, который принимают эти структуры как параметры. Т.е. типичный функциональный стиль.

Marinavo_0507

А в соседнем разделе не написано, как дотнетовцы это называют? Интересно.

Marinavo_0507

От темы разговор увёл ты, когда заявил, что задача излишне сложная. Разработчики squid так не считали, несмотря на то, что писали на C. Не оттого ли, что им не нужно было иметь свой мозг иерархиями классов и деструкторами?
Да, а ждать, пока вообще появится хоть один сидер тебе приятно? Не говори ерунды, на общую скорость распространения торрентов подобные технические мелочи не влияют.
Кроме скорости, есть ещё впечатление пользователей. Вижу, что понятие обратной связи тебе мало что говорит.

Marinavo_0507

Примером неизбежности циклических ссылок никогда не может быть какой-то программный продукт в целом. Надо приводить локальные задачи.
Локальные задачи на то и локальны, что можно охватить их взглядом целиком, с точностью до всех деталей. В таких задачах можно вручную проследить время жизни всех объектов и т.п., а также провести все оптимизации.
Интерес представляют более сложные приложения.

Marinavo_0507

При взаимодействии через третье лицо, как я описал выше, необходимости в циклических ссылках не будет.
Зато будет лишний indirection, а то и поиск в хеш-таблице или в чём похуже.
Прощай, хвалёная эффективность С++!

kokoc88

От темы разговор увёл ты, когда заявил, что задача излишне сложная. Разработчики squid так не считали, несмотря на то, что писали на C. Не оттого ли, что им не нужно было иметь свой мозг иерархиями классов и деструкторами?
Я сказал, что задача излишне сложная И решается без циклических ссылок. После того, как я прочитал rfc по проксям и http, я даже лезть внутрь squid не буду. Сразу скажу, что он работает не так, как ты описываешь.
Кроме скорости, есть ещё впечатление пользователей. Вижу, что понятие обратной связи тебе мало что говорит.

Со впечатлением пользователей всё будет одинаково в любом случае: файл скачается ровно за то же самое время. Впрочем, это опять далеко от темы.

Marinavo_0507

После того, как я прочитал rfc по проксям и http, я даже лезть внутрь squid не буду. Сразу скажу, что он работает не так, как ты описываешь.
Что в rfc навело тебя на такую мысль? Я тоже их читал, если что.

kokoc88

Циклические ссылки очень часто возникают. Например в ГУИ, есть контейнер с элементами-контролами, которые ссылаются на контейнер. Плюс подписка обработчиков на события. В итоге довольно не тривиальная структура с циклическими ссылками, которая заставляет напрягаться и придерживаться определенного протокола при удалении такой структуры. Не знаю, но меня лично напрягало это довольно сильно, когда приходилось разрабатывать свои структуры на СОМ, и ATL со своими смарт поинторами, конечно делали код чище, но в этой проблеме не помогали. И от общих усилий, затрачиваемых на проектирование и кодирование, это все занимало существенную часть.
ГУИ красивее и легче всего ложится на иерархию: у одного окна в 99.9% случаев один родитель. (Многие в данной теме так же путают, что ссылаться и иметь +1 счётчик - это, вообще говоря, разные вещи.) Если для разработки GUI тебе ришлось писать что-то жутко сложное с циклическими ссылками - это, всё таки, проблема не Си++, а скорее наличия опыта решения подобных задач. В этой теме уже не раз писалось о том, что к программированию надо относиться аккуратно, и если что-то можно сделать криво, то вовсе не обязательно делать это криво.
В качестве эксперимента предлагаю взять одну из библиотек из GC среды и переделать под C++ с подсчетом ссылок. Причем взять лучше что-нибудь современное, что от начала и до конца разрабатывалось под .NET — предлагаю WPF. Уверен, что если что-то и получиться, то это будет абсолютно не юзабельным для пользователя библиотеки.

Я не буду заниматься такой ерундой. На языке без GC задачи стоит решать другим способом. Язык без GC не проще, не сложнее, он просто другой. Выше в теме я уже приводил примеры, где спотыкаются языки с GC. Тема переросла в жёсткий подсчёт ссылок, причём по совершенно непонятным причинам.

kokoc88

Что в rfc навело тебя на такую мысль? Я тоже их читал, если что.
Не только в rfc, а в целом качество приводимых в этой теме аргументов. Впрочем, даже если я принимаю твои слова про squid, и принимаю требуемую сложность задачи, то всё равно никак не могу понять, зачем делать что-то с циклическими ссылками. Нет конкретики: как и в примере с КР2 всё можно решить проще.

kokoc88

Потому что этот "контроллер" является неочевидной и,
вообще говоря, излишней сущностью, которая является
затычкой к случаю, из-за отсутствия автоматического
управления памятью.
Ты почему оторвался от ботания матчасти? Теперь мне очевиден твой третий глобальный недостаток: к тому, что ты не умеешь программировать и не разбираешься в теме программирования вообще, ты ещё и нисколько не представляешь, каким образом решаются различного рода прикладные задачи. Лол, Кохтпа, столько слов на этом форуме, а правда одна: ты пустозвон, который ничего не умеет, мало чего знает, но при этом начитался всякой ерунды и слепо следует за ней в никуда.
Как я уже рекомендовал тебе выше: подучи матчасть, хорошенько подумай, и давай вместе посмеёмся над очередным бредом, который я цитирую выше.
> Созвездие в КР2 вообще не нужно делать объектом,
> а скорее свойством звезды.
Это такая разновидность "объектноориентированности",
когда сущность, являющуюся самостоятельным объектом,
понижают в ранге и вообще объявляют свойством.

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

Опять 25 - Кохтпа пишет чушь, не понимает предмета обсуждения, но лезет со своими коментариями. Я уже приготовил попкорн (несмотря на то, что сам буду одним из актёров правда, боюсь подавиться (смеяться часто приходится). Сказано было: иди учиться программировать и решать простейшие задачи. Если лезешь с аргументами, рассматривай обе стороны вопроса, а не минусы одной стороны. Впрочем, чего ждать от однобокого?
PS Кстати, Кохтпа ставит столько переводов строки, потому что пользуется неудобным браузером. Или просто не умеет пользоваться браузером...

kokoc88

Да, С++ники такие. Сегодня по приколу зашел в С++ раздел на rsdn и увидел замечательную тему про "свободный" интерфейс. Суть этой модной технологии сводится к проганью структур с данными + функций, который принимают эти структуры как параметры. Т.е. типичный функциональный стиль.
А тебе стоило прочитать хоть часть этой темы, прежде чем сюда влезать. В данной ветке есть как минимум два типа людей: одни существенную часть времени программировали на языках с GC, и видеть ничего кроме этого не могут, потому что не научены. Другая часть никогда не писала на языках с GC и считает своим долгом защищать Си++. Очень мало кто здесь программировал достаточно долго на обоих видах языков программирования, чтобы иметь представление о том, что GC - далеко не панацея. (Только Кохтпа писал лольные отмазки про модификацию GC для освобождения ресурсов, при этом всё жаловался, что никто не знает, как работают GC.) А уж о том, чтобы понять, что в Си++ при решении огромного множества подзадач утечек как таковых вообще не бывает, я лучше промолчу. Скажу только, что если задачу можно решить плохо, то вовсе не обязательно так и делать.

Marinavo_0507

Нет конкретики: как и в примере с КР2 всё можно решить проще.
Выше есть примеры, что под "проще" плюсовики часто понимают "сложнее".

kokoc88

Выше есть примеры, что под "проще" плюсовики часто понимают "сложнее".
Проблема в том, что не только плюсовики. И ещё есть проблема в том, что простые решения зачастую бывают неправильными (там недоглядели, тут недописали, а выглядит удобно и красиво).

Ivan8209

>> Потому что этот "контроллер" является неочевидной и,
>> вообще говоря, излишней сущностью, которая является
>> затычкой к случаю, из-за отсутствия автоматического
>> управления памятью.
> ты ещё и нисколько не представляешь, каким образом
> решаются различного рода прикладные задачи.
Зато ты прекрасно всё знаешь.
Уже давно известно, что задачи можно усложнять введением
дополнительных сущностей сколько душе угодно. Затык
только в том, что излишнесть этих сущностей проявляется
на более высоком уровне познания, подобно тому, как за
многими сложениями и перемножениями не сразу можно
увидеть действия с векторами и матрицами.
>>> Созвездие в КР2 вообще не нужно делать объектом,
>>> а скорее свойством звезды.
>> Это такая разновидность "объектноориентированности",
>> когда сущность, являющуюся самостоятельным объектом,
>> понижают в ранге и вообще объявляют свойством.
> Не лезь в спор, не зная предмета обсуждения.
> Ты только что написал очередную чушь.
Тебе, примитивномыслящему, тяжело понять, где ты порешь
откровенную чушь. В добавок, у тебя ещё и гонору столько,
что проще списать свою дремучесть на якобы мою.
>>> При взаимодействии через третье лицо, как я описал выше,
>>> необходимости в циклических ссылках не будет.
>> То есть, для того, чтобы избежать циклических ссылок, вместо
>> приличных средств управления памятью, которые надо сделать
>> один раз и навсегда, надо каждый раз изобретать третьи лица.
>> Вместо общего решения каждый раз изобретать костыль к случаю.
> Опять 25
Для того, чтобы написать "опять", надо прежде написать хотя
бы раз, чего ты не сделал.
> Если лезешь с аргументами, рассматривай обе стороны
> вопроса, а не минусы одной стороны.
Обе стороны и рассмотрены: там, где развитые языки дают
удобные, а то и полностью автоматические средства, языки
сёвого направления, в лучшем случае предоставляют какие-то
малофункциональные обрубки.
> PS Кстати, Кохтпа ставит столько переводов строки,
> потому что пользуется неудобным браузером.
Ограничение в 64 знака зашито мною лично.
---
"Аллах не ведёт людей неверных."

bastii

ГУИ красивее и легче всего ложится на иерархию: у одного окна в 99.9% случаев один родитель. (Многие в данной теме так же путают, что ссылаться и иметь +1 счётчик - это, вообще говоря, разные вещи.) Если для разработки GUI тебе ришлось писать что-то жутко сложное с циклическими ссылками - это, всё таки, проблема не Си++, а скорее наличия опыта решения подобных задач. В этой теме уже не раз писалось о том, что к программированию надо относиться аккуратно, и если что-то можно сделать криво, то вовсе не обязательно делать это криво.
Ну в С++ у меня иногда нет выбора. Так, например, циклические ссылки заложены уже базовые интерфейсы, на которых строятся ActiveX. Дальше, повторяюсь, регистрация обработчиков событий, и как развитие этого data binding.
Про "относиться аккуратно", "наличие опыта" никто не спорит. Но почему у меня должна голова болеть там, где в этом нет необходимости. В Winforms как раз вызов методов Dispose (где выполняется то, что выходит за рамки управления памятью, которое выполняет GC) выполняется по иерархии. Только такая модель (совместно с GC) позволяет написать библиотеку как Winform, где у пользователя этой библиотеки совсем ("в 99% случаев") эти проблемы не видны. Т.е. у меня, как разработчика библиотеки (пусть даже внутренней, как часть кода в моем проекте есть возможность спрятать все эти проблемы на определенном уровне в моем коде. Дальше я могу работать с более простой моделью, которую делает возможной GC. Причем, затрачивая дополнительные усилия на разработку библиотеки (т.е. определенного уровня кода я могу постоянно оптимизировать ее как с точки зрения простоты и удобности использования, так и с точки зрения производительности (причем простота не в ущерб производительности). Все это, конечно требует больший усилий от разработки библиотеки, но по крайней мере у меня есть такая возможность. Как далеко в этом следует заходить решать мне.
В твоем же случае, я не могу отгородить пользователя от всех проблем, связанных с управлением памятью, так как в С++ нет такого механизма, который я смогу там реализовать и использовать, чтобы сделать жизнь пользователя проще, как это позволяет сделать среда с GC.
А то, что ты говоришь примерно похоже на следующее: "я тут N лет программировал на ассемблере, и могу делать это быстро и качественно, а если у вас есть с этим какие-то проблемы, например, не получается эффективно локальные данные размещать в ограниченном наборе регистров, то что я могу сказать — к программированию нужно относиться аккуратнее ..., видимо не хватает опыта".
Вообще не понимаю о чем идет спор. Есть определенные преимущества, которые дает GC, ими кстати тоже надо научиться пользоваться (не уверен, что у каждого мега опытного С++ программиста это быстро получиться).
Лично мне нравиться так среда с GC, которая есть в Java и .NET. Поэтому там, где это возможно и уместно, я предпочту Java или .NET и буду пользоваться теми преимуществами, которые получаю с ними. Других случаях, если очень надо, будет C++, ассемблер или еще что — надеюсь это буду прогать не я .

kokoc88

Зато ты прекрасно всё знаешь.
Уже давно известно, что задачи можно усложнять введением
дополнительных сущностей сколько душе угодно. Затык
только в том, что излишнесть этих сущностей проявляется
на более высоком уровне познания, подобно тому, как за
многими сложениями и перемножениями не сразу можно
увидеть действия с векторами и матрицами.
Блаблабла. Ещё один маразм. Ты никогда не пробовал изъясняться на Русском языке? Кажется, нет. Ровно как и пытаться хоть немного вникнуть в смысл слов, которые тебе говорят. И поэтому говорить просто бесполезно: перечитай ещё раз всё, что я тебе написал в предыдущем посте. Поботай матчасть. Подумай головой, на худой конец. Если она у тебя ещё способна на это.
>> Это такая разновидность "объектноориентированности",
>> когда сущность, являющуюся самостоятельным объектом,
>> понижают в ранге и вообще объявляют свойством.
> Не лезь в спор, не зная предмета обсуждения.
> Ты только что написал очередную чушь.
Тебе, примитивномыслящему, тяжело понять, где ты порешь
откровенную чушь. В добавок, у тебя ещё и гонору столько,
что проще списать свою дремучесть на якобы мою.

О, да, ты ведь у нас Великий Кохтпа! Ужасный и могучий! Всезнающий! На деле ты просто ноль без палки и лезешь в темы, в которых ничего не понимаешь. В этом твоя проблема: очень хочешь, чтобы тебя все слушали и восторгались, только вот знать ты ничего не знаешь. Вот и мелешь впустую какую-то ерунду, в которой сам постоянно запутываешься. Я уже не говорю о банальном - попытаться послушать, что тебе пишут другие люди. (Когда-то в Common тебе уже предлагали билеты в цирк, в кукольный театр, в зоопарк. Тяжелое детство, что сказать.) Дремучесть твоя, она не якобы, она очевидна.
Для того, чтобы написать "опять", надо прежде написать хотя
бы раз, чего ты не сделал.

Хотя бы раз написал ты.
> Если лезешь с аргументами, рассматривай обе стороны
> вопроса, а не минусы одной стороны.
Обе стороны и рассмотрены: там, где развитые языки дают
удобные, а то и полностью автоматические средства, языки
сёвого направления, в лучшем случае предоставляют какие-то
малофункциональные обрубки.

Обе стороны рассмотрены другими людьми. А ты просто продолжаешь баранить и писать глупости. Их уже даже не интересно читать.
> PS Кстати, Кохтпа ставит столько переводов строки,
> потому что пользуется неудобным браузером.
Ограничение в 64 знака зашито мною лично.

Ага, ты у нас весьма ограниченный.

kokoc88

Ну в С++ у меня иногда нет выбора. Так, например, циклические ссылки заложены уже базовые интерфейсы, на которых строятся ActiveX. Дальше, повторяюсь, регистрация обработчиков событий, и как развитие этого data binding.
Тут стоило бы написать, в какие из них. Причём надо писать не о том, что они заложены; а что они заложены именно так, что ты сам должен заботиться о них. И что их создаёт именно библиотека, а не ты сам.
Про "относиться аккуратно", "наличие опыта" никто не спорит. Но почему у меня должна голова болеть там, где в этом нет необходимости. В Winforms как раз вызов методов Dispose (где выполняется то, что выходит за рамки управления памятью, которое выполняет GC) выполняется по иерархии. Только такая модель (совместно с GC) позволяет написать библиотеку как Winform, где у пользователя этой библиотеки совсем ("в 99% случаев") эти проблемы не видны.
Ты не представляешь, как много проблем у Winforms и платформы .NET в целом. Проблемы там прекрасно видны: забудь обернуть в using вызовы к web client и получишь засорение тред пула, на котором выполняются запросы. Отдай какому-нибудь живучему объекту эвент, реализованный твоим классом, забудь его отписать, и получишь утечку памяти. Или попытайся выполнить операцию ожидания в finally (несмотря на то, что это ошибка, которая описана в документации, я считаю это недостатком).
Дальше я могу работать с более простой моделью, которую делает возможной GC. Причем, затрачивая дополнительные усилия на разработку библиотеки (т.е. определенного уровня кода я могу постоянно оптимизировать ее как с точки зрения простоты и удобности использования, так и с точки зрения производительности (причем простота не в ущерб производительности). Все это, конечно требует больший усилий от разработки библиотеки, но по крайней мере у меня есть такая возможность. Как далеко в этом следует заходить решать мне.

Эх, опять более простые модели. Их не бывает, GC тебе никак не поможет в добрых 90% случаев. Ты написал очень общие понятия, которые, скорее, можно применять к любому языку. Нужно больше конкретики, если ты хочешь показать наличие проблемы.
В твоем же случае, я не могу отгородить пользователя от всех проблем, связанных с управлением памятью, так как в С++ нет такого механизма, который я смогу там реализовать и использовать, чтобы сделать жизнь пользователя проще, как это позволяет сделать среда с GC.
Это ты в своём случае не можешь. В других случаях надо ставить задачу и сравнивать решения. Это либо даст шанс найти более хорошее решение с той или другой стороны, либо будет аргументом в споре.
А то, что ты говоришь примерно похоже на следующее: "я тут N лет программировал на ассемблере, и могу делать это быстро и качественно, а если у вас есть с этим какие-то проблемы, например, не получается эффективно локальные данные размещать в ограниченном наборе регистров, то что я могу сказать — к программированию нужно относиться аккуратнее ..., видимо не хватает опыта".
Плохо, что тебе так показалось. Вообще-то я последнее время больше программировал на Java/C#, чем на Си++. И поэтому я считаю, что мне более-менее видны проблемы языков со сборкой мусора и без оной. И моё мнение на этот счёт пока что остаётся вполне определённым. Деструкторы позволяют избежать почти любых проблем с утечками ресурсов, хотя и не являются панацеей от всех бед. GC требует постоянно следить за тем, что ты делаешь в коде, и требует очень аккуратного подхода к написанию программ. Зачастую приходится писать более аккуратно, чем на Си++.
Вообще не понимаю о чем идет спор. Есть определенные преимущества, которые дает GC, ими кстати тоже надо научиться пользоваться (не уверен, что у каждого мега опытного С++ программиста это быстро получиться).

Ага. А уж как хорошо это не получается у людей, которые до этого вообще не писали ни на каком языке, и которые считают, что GC спасает от всех проблем...
Лично мне нравиться так среда с GC, которая есть в Java и .NET. Поэтому там, где это возможно и уместно, я предпочту Java или .NET и буду пользоваться теми преимуществами, которые получаю с ними. Других случаях, если очень надо, будет C++, ассемблер или еще что — надеюсь это буду прогать не я .

Жизнь иногда заставляет учиться разным вещам. Мне как-то пришлось почти два месяца писать логику на JavaScript. И если ты не Кохтпа, который только и умеет чесать языком, то сможешь научиться писать на чём угодно, решать задачи красиво, и извлекать из этого выгоду.

Ivan8209

>> Уже давно известно, что задачи можно усложнять введением
>> дополнительных сущностей сколько душе угодно. Затык
>> только в том, что излишнесть этих сущностей проявляется
>> на более высоком уровне познания, подобно тому, как за
>> многими сложениями и перемножениями не сразу можно
>> увидеть действия с векторами и матрицами.
> Ты никогда не пробовал изъясняться на Русском языке?
> Кажется, нет.
В тобой же приведённой цитате ровно _два_ иностранных
слова, все остальные взяты из русского языка. В качестве
домашнего задания можешь взять отыскание эти двух слов.
>> Для того, чтобы написать "опять", надо прежде написать хотя
>> бы раз, чего ты не сделал.
> Хотя бы раз написал ты.
Я тебе и писал, в ответ получая постоянные "учи матчасть"
без единого обоснования. Отсюда вывод: ты нисколько не
способен ни разобраться в той самой матчасти (а ты ведь
не знаешь ни одного языка программирования другого,
отличающегося от сишного направления ни уяснить
устройства сборщиков мусора (а тебе известен только
подсчёт ссылок ни даже объяснить своей точки зрения
на проблему.
>>> Если лезешь с аргументами, рассматривай обе стороны
>>> вопроса, а не минусы одной стороны.
>> Обе стороны и рассмотрены: там, где развитые языки дают
>> удобные, а то и полностью автоматические средства, языки
>> сёвого направления, в лучшем случае предоставляют какие-то
>> малофункциональные обрубки.
> Обе стороны рассмотрены другими людьми. А ты просто
> продолжаешь баранить и писать глупости. Их уже даже
> не интересно читать.
Это заметно, что ты старательно опускаешь все обоснования,
а отвечаешь исключительно на мелочи, и исключительно руганью.
У меня есть только одно объяснение последнему факту:
ты не смыслишь в программировании ни чёрта, почему
и не разобрался в избыточности заведения третьих сущностей
для описания циклических структур.
---
"Аллах не ведёт людей неверных."

Ivan8209

>> А то, что ты говоришь примерно похоже на следующее:
>> "я тут N лет программировал на ассемблере, и могу делать
>> это быстро и качественно, а если у вас есть с этим какие-то
>> проблемы, например, не получается эффективно локальные
>> данные размещать в ограниченном наборе регистров, то
>> что я могу сказать — к программированию нужно относиться
>> аккуратнее ..., видимо не хватает опыта".
> Плохо, что тебе так показалось. Вообще-то я последнее
> время больше программировал на Java/C#, чем на Си++.
> И поэтому я считаю, что мне более-менее видны проблемы
> языков со сборкой мусора и без оной.
Тебе постоянно указывают на то, что "Java/C#" не описывают
области языков со сборкой мусора, мало того, сборка мусора
в них сделана отстойно, и их пример в расчёт приниматься не может.
Хочешь приводить примеры --- бери языки семейства лисп или МЛ.
Но их ты не знаешь, и поэтому придумываешь какие-то
несуществующие проблемы.
---
"Narrowness of experience leads to narrowness of imagination."

Marinavo_0507

Вообще-то я последнее время больше программировал на Java/C#, чем на Си++.
Это многое объясняет. А вот мне, прежде чем заставить программировать на Java, показали ML. Чтоб я не думал, будто везде такое же говно, и так и надо.

psm-home

Тебе постоянно указывают на то, что "Java/C#" не описывают
области языков со сборкой мусора, мало того, сборка мусора
в них сделана отстойно, и их пример в расчёт приниматься не может.
О, кстати, а можно ссылочку, где можно прочесть, чем сборка мусора, например в Java, хуже, чем, например в каком-нибудь из ML'ей? Ну или что-то в этом роде, короче говоря любую ссылку, которая подтвердит процитированное высказывание.

poi1981

>прежде чем заставить программировать на Java, показали ML
ML показали, а писать таки заставили на яве? что ж так?

Marinavo_0507

требования заказчика
разрабатывался инструмент для быдлокодеров(tm поэтому видимая им часть должна была быть на яве
невидимые части писались на ML и на прологе ещё

poi1981

эх, как красиво начинал - про обратную связь, про впечатление пользователей, а продался за какие-то там требования заказчика
не удивлюсь, если ещё через полтысячи постов выяснится, что Контра, скажем, пишет в настоящий момент нечто комерческое на VB

Marinavo_0507

дык маленький был, не был знаком с рынком труда
это ж давно было

Ivan8209

> не удивлюсь, если
Можешь удивляться.
---
"Верь сводке погоды, но доверяй --- интуиции."
P.S. На этой неделе --- EmacsLisp.

Hastya

Тебе постоянно указывают на то, что "Java/C#" не описывают
области языков со сборкой мусора, мало того, сборка мусора
в них сделана отстойно, и их пример в расчёт приниматься не может.
Вообще в Java 1.5 - один из лучших современных сборщиков мусора, хорошо работающий даже на кучах размером 4 гига и больше не думаю, что это пример отстойности =)

kokoc88

Это многое объясняет. А вот мне, прежде чем заставить программировать на Java, показали ML. Чтоб я не думал, будто везде такое же говно, и так и надо.
Многое объясняет что? Привожу некоторые цитаты про OCaml.
Unlike the Java GC, which gives GCs a bad name, the OCaml GC doesn't allocate huge amounts of memory at start-up, nor does it appear to have arbitrary fixed limits that need to be overridden by hand.
Это типа плюс GC OCaml. Не помню кто, но кто-то из "ненасильников" всё время кричит, какие дешёвые нынче компьютерные ресурсы.
Calls to read_file open the file but don't close it. Because OCaml uses a full garbage collector chan isn't collected until some time later when the minor heap becomes full. In addition, OCaml will not close the channel when it collects the handle's memory. So this program would eventually run out of file descriptors.
Это типа минус GC OCaml. Такой же, как и описывалось выше. Короче, те же уши, вид сбоку. Если же у тебя есть коментарии по существу, было бы неплохо после своих заявлений эти коментарии озвучивать.
Edit:
 
The OCaml GC is synchronous. It doesn't run in a separate thread, and it can only get called during an allocation request.

А вот это ещё один огромный минус. Впрочем, не всегда огромный.

kokoc88

> не удивлюсь, если
Можешь удивляться.
Кохтпу не пустят программировать на VB. Слишком скудоумен для этого.
P.S. На этой неделе --- EmacsLisp.

НЖ большая КН.

kokoc88

> Ты никогда не пробовал изъясняться на Русском языке?
> Кажется, нет.
В тобой же приведённой цитате ровно _два_ иностранных
слова, все остальные взяты из русского языка. В качестве
домашнего задания можешь взять отыскание эти двух слов.
Ну вот, Кохтпа опять не видит дальше одного топика. Я тебе не про иностранные слова писал, дурачок. Такое понятие, как образное выражение, тебе явно не знакомо. В качестве домашнего задания прочитай учебник по литературе для третьего класса.
Я тебе и писал, в ответ получая постоянные "учи матчасть"
без единого обоснования. Отсюда вывод: ты нисколько не
способен ни разобраться в той самой матчасти (а ты ведь
не знаешь ни одного языка программирования другого,
отличающегося от сишного направления ни уяснить
устройства сборщиков мусора (а тебе известен только
подсчёт ссылок ни даже объяснить своей точки зрения
на проблему.

Постоянные "учи матчасть" ты получаешь только по причине скудного умишка. Не разобравшись в теме кидаешься критиковать. Вот и вся твоя сущность. Свою точку зрения на проблему я всегда объясняю, и всегда пишу о том, как стоило бы решать проблему. Далеко ходить не надо: возьмём задачу про игру КР2. Ты наехал на предложенное качественное решение, явно не зная, как эта игра устроена. Ты начал писать какие-то свои мысли по поводу стороннего объекта, который контролирует поведение других объектов. При этом ты написал полный нонсенс на счёт того, что в языках с GC это всё было бы красиво и без лишней ручной работы. Просто потому, что ты даже не задумался о том, какая на самом деле стоит задача. Из-за своей недальновидности ты не понял, что в предложенном автором темы решении GC спасуют точно так же, как и подсчёт ссылок. К учению матчасти с сегодняшенго дня будем добавлять: учись слушать других людей.
> Обе стороны рассмотрены другими людьми. А ты просто
> продолжаешь баранить и писать глупости. Их уже даже
> не интересно читать.
Это заметно, что ты старательно опускаешь все обоснования,
а отвечаешь исключительно на мелочи, и исключительно руганью.

Какие нахер обоснования? Ты в проблеме ничего не понимаешь. И все твои посты содержат только воду, причём пресную. Потому что нормальные посты - это когда вместо голой и неправильной критики пишут своё решение проблемы. Сравнивают и говорят, почему лучше. А не орут "насильники", "насильники", как будто ошпарили яйца.
У меня есть только одно объяснение последнему факту:
ты не смыслишь в программировании ни чёрта, почему
и не разобрался в избыточности заведения третьих сущностей
для описания циклических структур.

Согласен. Чёрта в программировании смыслишь только ты. Остального ты просто не видишь - слишком далеко от твоего носа.

kokoc88

Тебе постоянно указывают на то, что "Java/C#" не описывают
области языков со сборкой мусора, мало того, сборка мусора
в них сделана отстойно, и их пример в расчёт приниматься не может.
Хочешь приводить примеры --- бери языки семейства лисп или МЛ.
Но их ты не знаешь, и поэтому придумываешь какие-то
несуществующие проблемы.
Вот когда пишут "какие-то несуществующие проблемы" обычно указывают какие именно. Выше по теме проблема GC OCaml, точно такая же, как описана для любого другого GC. Плюс ко всему, ты опять не разобрался с темой. Ты не знаешь, как реализована сборка мусора в Java/C#, да и вообще, как она где-то реализована. Ты не прочёл про проблемы, на которые указывали в языках с GC. Ты опять баранишь.

kokoc88

О, кстати, а можно ссылочку, где можно прочесть, чем сборка мусора, например в Java, хуже, чем, например в каком-нибудь из ML'ей? Ну или что-то в этом роде, короче говоря любую ссылку, которая подтвердит процитированное высказывание.
Ссылки, подтверждающей процитированное высказывание быть не может. У них там свои плюсы и минусы, которые, к тому же, работают в разных условиях как минусы и плюсы.

enochka1145

Мегареспект за терпение и юмор!
2 __No__: не нравится - попробуй игнор.

Marinavo_0507

Вообще в Java 1.5 - один из лучших современных сборщиков мусора, хорошо работающий даже на кучах размером 4 гига и больше
Так говорили про каждую версию, начиная с 1.2.

Marinavo_0507

В детялях реализации GC я не силён.
Под словом "говно" я понимаю уродство языка (руками на яве писать очень неприятно, когда я ушёл из того проекта, там, по рассказам, отказались от этой практики - почти весь код генерировали в котором всё нужно писать по 2-3 раза, а также тормознутость, как воспринимаемая субъективно, так и на бенчмарках. В частности, среди задач, которыми мы занимались, я не осилил подобрать бенчмарк, показывающий преимущество явы в эффективности (по сравнению с некоторой устаревшей технологией). Объекты крайне медленно создавались. Это была версия 1.2.
Не помню кто, но кто-то из "ненасильников" всё время кричит, какие дешёвые нынче компьютерные ресурсы.
Ресурсы дешевы, но манера Java VM сначала съедать гиг памяти, и только потом начинать что-то делать, сильно ограничивает её область применения.

Hastya

Так говорили про каждую версию, начиная с 1.2.
Естественно, ведь GC совершенствуется с каждой версией.
В 1.6 GC еще лучше.

kokoc88

Под словом "говно" я понимаю уродство языка (руками на яве писать очень неприятно, когда я ушёл из того проекта, там, по рассказам, отказались от этой практики - почти весь код генерировали в котором всё нужно писать по 2-3 раза, а также тормознутость, как воспринимаемая субъективно, так и на бенчмарках.
Уродство языка - это вещь субъективная. Я уже давно перестал упоминать "<<<>>>> -> :: -> | ". Ты бы лучше привёл сравнения, мол вот "такие-то вещи пишутся так и эдак", "неудобно-некрасиво потому что", "ведёт к ошибкам так как".
В частности, среди задач, которыми мы занимались, я не осилил подобрать бенчмарк, показывающий преимущество явы в эффективности (по сравнению с некоторой устаревшей технологией). Объекты крайне медленно создавались. Это была версия 1.2.
Версия 1.2 была в 98 году. Странно, что медленно создавались объекты. Вообще в Java они обычно создаются быстрее, чем в любом другом языке. (Мне кажется, что в 98 году кроме как на Си++ и MFC вообще старались не писать, т.к. компы просто не тянули. По крайней мере, я помню стандартные требования на работу программистом в те годы, типа COM/DCOM, MFC, MSVS 6.0, ...)
Ресурсы дешевы, но манера Java VM сначала съедать гиг памяти, и только потом начинать что-то делать, сильно ограничивает её область применения.

Не преувеличивай. Мне тяжело представить, как надо намудрокодить, чтобы сразу требовался гиг памяти. У меня сейчас сервер CRM работает с более чем 100.000 объектов, пожирает 150 МБ.

Marinavo_0507

Естественно, ведь GC совершенствуется с каждой версией.
Вот когда перестанут каждый раз кричать "вот у нас наконец-то заебатый GC", можно будет сделать вывод, что он получился хорошим.

Hastya

Вот когда перестанут каждый раз кричать "вот у нас наконец-то заебатый GC", можно будет сделать вывод, что он получился хорошим.
чем рассуждать, какой GC лучше, скачал бы для начала сановский GC и попробовал
Я уж не говорю про альтернативные реализации типа JRockit и IBM

Marinavo_0507

Я уже давно перестал упоминать "<<<>>>> -> :: -> | ".
Это С++ штоле? Набор скобок характерный.
Ты бы лучше привёл сравнения, мол вот "такие-то вещи пишутся так и эдак", "неудобно-некрасиво потому что", "ведёт к ошибкам так как".
Есть объективные показатели, например длина кода и количество лишних сущностей (то есть, не имеющих аналога в предметной области, а нужных лишь для реализации). Эти параметры коррелируют, так как у большинства языков длина типичных синтаксических элементов различается не сильно (это или недлинное слово, или один или несколько знаков препинания).
В этом и других подобных тредов замечено, что решения плюсовиков содержат явный избыток сущностей, а на яве - примерно то же, но только ещё часть из них повторена по 2-3 раза.
Версия 1.2 была в 98 году. Странно, что медленно создавались объекты. Вообще в Java они обычно создаются быстрее, чем в любом другом языке.
Я имел с ней дело в 2000 и 2001 г. Возможно, уже тогда на 1.3 перешли, я точно не помню, так как производительность от этого не выросла, и язык не поменялся (generics были добавлены позже, кажется).
Вообще в Java они обычно создаются быстрее, чем в любом другом языке.
Непохоже, что ты в курсе про любой другой язык.
С чем сравнивал-то? C PHP и perl что ли?

Marinavo_0507

попробую как-нибудь
торопиться некуда, учитывая, что раньше такие обещания оказывались лишь лозунгами

kokoc88

Это С++ штоле? Набор скобок характерный.
Нет, это лиспообразные.
Есть объективные показатели, например длина кода и количество лишних сущностей (то есть, не имеющих аналога в предметной области, а нужных лишь для реализации). Эти параметры коррелируют, так как у большинства языков длина типичных синтаксических элементов различается не сильно (это или недлинное слово, или один или несколько знаков препинания).
В этом и других подобных тредов замечено, что решения плюсовиков содержат явный избыток сущностей, а на яве - примерно то же, но только ещё часть из них повторена по 2-3 раза.

Где замечено, что замечено? Я ничего не заметил. (Разве что почти полную недоступность для начинающих всяких классных языков программирования, типа лиспов-прологов-млей.) Можешь привести код, лично твой, чтобы можно было строить сравнения? Если опираться на код людей, которые плохо программируют, то изврат будет в любом случае. И язык программирования тут ничем помочь не сможет. Иначе опять получается ничем не подтверждённое заявление о том, как плохо живётся программистам на Java.
Я имел с ней дело в 2000 и 2001 г. Возможно, уже тогда на 1.3 перешли, я точно не помню, так как производительность от этого не выросла, и язык не поменялся (generics были добавлены позже, кажется).

Производительность Java сильно выросла. И я не думаю, что всё это время производительность того же OCaml была постоянной. Если за языком программирования не следят, то его рано или поздно вытеснят.
Непохоже, что ты в курсе про любой другой язык.
С чем сравнивал-то? C PHP и perl что ли?

Я выше цитировал особенности GC OCaml. Если ты их не опроверг, то я могу спокойно утверждать, что Java делает объекты быстрее, чем OCaml. Тоже самое относится к созданию объектов "в лоб" на Си++. (Конечно, при грамотном подходе быстрее всех будет именно Си++.)

kokoc88

Нет, это лиспообразные



































Marinavo_0507

тебя в детстве учебником по лиспу не били?

kokoc88

тебя в детстве учебником по лиспу не били?
Меня нет, а тебя?

Marinavo_0507

а чем били?
целый экран скобок просто так не пишут

kokoc88

а чем били?

Бьют не всех, не суди людей по себе.
целый экран скобок просто так не пишут
А ты не смог разглядеть, что там написано? Как же так, ведь форматирование такое удобное и красивое.

Marinavo_0507

Чуве, расслабься. Что бы не происходило с тобой в детстве, это давно позади. Сходи к психотерапевту, что ли.

kokoc88

Чуве, расслабься. Что бы не происходило с тобой в детстве, это давно позади. Сходи к психотерапевту, что ли.
Со мной в дестве всё было нормально. Я же не начинаю тем про то, чем кого-то били.
А вот что с тобой происходило - это действительно позади.

Maurog

я нашел одну незакрытую скобку.

kokoc88

я нашел одну незакрытую скобку.
Да. Низачёт мне по программированию.

sbs-66

Есть объективные показатели, например длина кода и количество лишних сущностей (то есть, не имеющих аналога в предметной области, а нужных лишь для реализации). Эти параметры коррелируют, так как у большинства языков длина типичных синтаксических элементов различается не сильно (это или недлинное слово, или один или несколько знаков препинания).В этом и других подобных тредов замечено, что решения плюсовиков содержат явный избыток сущностей, а на яве - примерно то же, но только ещё часть из них повторена по 2-3 раза.
Зато на Perl, например, код будет максимально короткий. Сущностей будет минимум, т.к. у него ебанутая объектная модель. Код будет очень коротоким, но абсолютно не читабельным и уж точно одноразовым.
То, что сложные и неинтуитивные вещи можно записать всего несколькими символами - это не плюс, а огромный минус. Так как если этим пользоваться, то твой код нельзя будет поддерживать, а если не пользоваться, то ты обретёшь излишний геморой, т.к. данный язык явно рассчитан не для тебя.
Ну, такая вот аналогия. Научные статьи содержат избыточное количество заумствований, да и на 90% избыточны. И кое что в них лишнее и создаёт авторам статей лишние проблемы. Однако если в этих статьях изъясняться на сленге, как принято в устной речи при обсуждении тех же проблем, что и в статьях, используя слова хреновина и фиговень, то твои статьи будут бесполезны и никто не сможет перевоспользоваться твоими результатами.
Ну вот, и теперь вам говорят, что в ттаком-то институте люди пишут таки статьи на сленге и публикуют. Большую часть статей понять не возможно, но немногие уважаемые многоопытные учёные мужи пытаются на этом сленге выразить свои мысли так, чтобы их можно было понять. То есть не пользуются теми преимуществами краткости, которые сленг даёт, но при этом не имеют преимуществ научной точности, которая есть у традиционного научного стиля. Ну, вроде как писать хорошие поддерживаемые программы на Perl.
Про другие языки с повышенной краткостью изложения говорить не могу, ибо опыта их использования мало. Может там и научились сочетать краткость и понятность. Однако гложат сомнения.
PS. Ежели кому интересно, то я могу написать пару примеров, как на С++ надо/можно реализовать логику в КР2, чтобы исключить ассес виолейшен и утечки памяти. А то как то все пришли к молчаливому согласию, что там всё сложно и не для С++, с чем я не согласен.

Marinavo_0507

Зато на Perl, например, код будет максимально короткий. Сущностей будет минимум, т.к. у него ебанутая объектная модель. Код будет очень коротоким, но абсолютно не читабельным и уж точно одноразовым.
На perl можно писать читаемый код.
А если пытаться сокращать, то сущностей там почти не убавится, но длина кода сократится - это особенность языка.
Поэтому я и предлагаю оценивать по этим двум показателям.
То, что сложные и неинтуитивные вещи можно записать всего несколькими символами - это не плюс, а огромный минус.
Я предлагаю записывать таким образом простые вещи.
А мне в ответ показывают, как на C++ это же делается с заведением отдельном месте новых классов и методов.

Marinavo_0507

Только что осмыслил этот пример.
Не впечатляет. Основная цель не достигнута - имя функции потеряно.

sbs-66

Я предлагаю записывать таким образом простые вещи.А мне в ответ показывают, как на C++ это же делается с заведением отдельном месте новых классов и методов.
Заведение для каждого логического механизма отдельного класса очень хорошо сказывается на читаемости кода. И этот совсем не сложно. И даже, что удивительно, позволяет избегать лишнего кода на передачу внутренних параметров механизма между методами.

Marinavo_0507

Заведение для каждого логического механизма отдельного класса очень хорошо сказывается на читаемости кода.
Не во всех случаях. А C++ заставляет это делать для всех. Тебе пришлось придумать гордое название "логический механизм", чтобы оправдать такое незаслуженное возвеличивание.
И этот совсем не сложно.
Аутотренинг
"Я не пёрнул, это не я!"
И даже, что удивительно, позволяет избегать лишнего кода на передачу внутренних параметров механизма между методами.
Прикинь, в нормальных языках такой проблемы просто нет. google:lexical+scoping google:closure

poi1981

>целый экран скобок просто так не пишут
Аутотренинг
"Я не пёрнул, это не я!"

nikita270601

Вот, наткнулся на прекрасное:
«10е правило программирования» гласит: «Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified bug-ridden slow implementation of half of Common Lisp»".

Olyalyau

написал замену map <string, list<string>>

А map на чёрно-красных или сбалансированных деревьях?
Если да, да за час написал — ты просто сенсей

Olyalyau

> следующее утверждение тоже верно "Если его можно написать на C++, то можно и на машине
> тьюринга", но практического смысла не имеет...
Ошибаешься, данное утверждение не верно.

Это ещё почему?

Papazyan

О, кстати, а можно ссылочку, где можно прочесть, чем сборка мусора, например в Java, хуже, чем, например в каком-нибудь из ML'ей? Ну или что-то в этом роде, короче говоря любую ссылку, которая подтвердит процитированное высказывание.
ML отличается от Java и т.п. тем, что там создается огромное количество мелких объектов с малым количеством обратных ссылок. В то время как в Java объекты создаются сравнительно редко, они большие и более сложные в инициализации, обратные ссылки, очевидно, часты. Отсюда простой вывод - сборщик мусора с поколениями (а если памяти много, он необходим) будет гораздо менее эффективен в случае императивных языков. Ему придется постоянно бороться с ссылками между поколениями. Хотя благодаря меньшему расходу памяти он будет вызываться реже, это компенсирует ущерб в какой-то мере.

Papazyan

Многое объясняет что? Привожу некоторые цитаты про OCaml.

Unlike the Java GC, which gives GCs a bad name, the OCaml GC doesn't allocate huge amounts of memory at start-up, nor does it appear to have arbitrary fixed limits that need to be overridden by hand.
Это типа плюс GC OCaml. Не помню кто, но кто-то из "ненасильников" всё время кричит, какие дешёвые нынче компьютерные ресурсы.

Calls to read_file open the file but don't close it. Because OCaml uses a full garbage collector chan isn't collected until some time later when the minor heap becomes full. In addition, OCaml will not close the channel when it collects the handle's memory. So this program would eventually run out of file descriptors.
Это типа минус GC OCaml. Такой же, как и описывалось выше. Короче, те же уши, вид сбоку. Если же у тебя есть коментарии по существу, было бы неплохо после своих заявлений эти коментарии озвучивать.
Edit:


The OCaml GC is synchronous. It doesn't run in a separate thread, and it can only get called during an allocation request.
А вот это ещё один огромный минус. Впрочем, не всегда огромный.
1) но не минус точно
2) недостаток, но за внешними ресурсами всегда приходиться следить самому.
3) в чем минус-то?

Hastya

Как раз в Java за счет наличия wrapper-классов (Integer, Long, etc.) порождается огромное количество мелких объектов. По статистике Sun, до 90-95% создаваемых объектов имеют очень малое время жизни, соответственно имеют хорошие шансы умереть в Eden Space.
Обратные ссылки действительно присутствуют ВСЕГДА (т.к. сами сущности Class и ClassLoader являются объектами но они в данном случае указывают на Permanent Space, который игнорируется GC.
Кроме того, String Pool имеет собственную схему распределения памяти.

kokoc88

1) но не минус точно
2) недостаток, но за внешними ресурсами всегда приходиться следить самому.
3) в чем минус-то?
1. В некотором смысле, конечно, не минус. Только вопрос в том, как выделяется дополнительная память при её нехватке. Если под каждый новый объект будет вызываться malloc, то скорость создания новых объектов будет плачевной. Впрочем, я не разбирался, как это работает в OCaml на самом деле.
2. Это было отмечено как недостаток решений с GC в целом, и конкретно OCaml тут не при чём. Выше по теме были дискуссии на этот счёт.
3. Я увидел минус в том, что GC синхронный. Вызывается во время размещения новых объектов. На многопроцессорных системах может быть выгоднее использовать асинхронный GC. (Отметим, что есть алгоритмы, которым не надо лочить все потоки и объекты в программе, чтобы собрать мусор.) Впрочем, я после этого отметил, что он может работать и более эффективно.

Landstreicher

Да, твой вариант во многом реализует функциональность макроса (не хватает только имени).
Я вырезал только небольшой кусок кода. Привожу более полный фрагмент:

#define FUNCLASS(type,fun,pars) \
struct fun##Class: public BaseClass { \
type result; \
fun##ArgStruct funargs; \
void do_work; \
virtual void work; \ {
result = do_work; \
} \
virtual const char* name const { return #fun; } \
virtual int class_id const { return TypeClassId<fun##Class>::class_id; } \
}; \
BaseClass* fun(pars) { \
f = new fun##Class; \
// вырезан код для инициализации аргументов funargs по pars
return f; \
}
type fun##Class::do_work \

Используется примерно так

FUNCLASS(double, myfunc, (int x, double y
{
// код X
}

При разворачивании макроса код X становится телом от метода fun##Class:do_work.
Нужно решить две задачи:
1) у функции может быть различное число аргументов (int x, double y). Шаблон не может иметь переменное число аргументов.
2) Нужно создавать объект у которого задается тело метода. Я не вижу способов как такое сделать на шаблоне.
PS. В некотором роде, этот макрос создает замыкание "руками".

Dasar

в чем отличие? от:

class myFuncClass:FunClass<double>
{
public:
double do_work(int x, int y)
{
}
};

где FunClass что-то типа вышеприведенного

Dasar

шаблоны неудобно использовать для syntactic shugar, остальные задачи они решают хорошо.
поэтому общепринятая практика:
1. функционал делается на шаблонах
2. syntactic shugar поверх функционала делается на макросах
соответственно в первом случае - мы имеем полноценную проверку кода от компилятора, а с помощью второго - уменьшает кол-во кода, который необходимо писать при каждом использовании

Landstreicher

> поэтому общепринятая практика:
> 1. функционал делается на шаблонах
> 2. syntactic sugar поверх функционала делается на макросах
+1. С такой формулировкой я согласен.
Насколько я понял, до этого ты говорил, что можно вообще обойтись без макросов.
Вобщем, суть тех макросов, которые я писал состоят в следующем. Хочется делать замыкания из функций, то есть писать что-то типа
НЕКИЙ_МАКРОС(тип, название, аргумент, что-то еще, возможно в другом порядке)
{
код функции
}
и получать при этом:
1) класс, который содержит функцию, аргументы вызова и переменную result. Класс должен реализовывать метод work который вызывает функцию с этими аргументами, и записывает результат в result;
2) предоставлять функцию, создающие объекты такого класса.
Если ты знаешь более нормальное решение (без макросов) напиши его. Как бы ты стал решать данную задачу?
Единственное решение которое я знаю — те макросы, которые я привел. Это грязный хак, но я не могу придумать ничего лучше. Я считаю, что это особенность С++, так как по крайней мере 3 известных мне языка позволяют делать подобные вещи без проблем.

Landstreicher

> в чем отличие? от:
x, y нужно куда-то сохранить, чтобы потом вызывать work. В объекте должны быть соответствующие поля:

class myFuncClass : FuncClass<double> {
int x; <-- это кто будет вставлять и как?
int y;
void work ...
...
};

Papazyan

3. Я увидел минус в том, что GC синхронный. Вызывается во время размещения новых объектов. На многопроцессорных системах может быть выгоднее использовать асинхронный GC. (Отметим, что есть алгоритмы, которым не надо лочить все потоки и объекты в программе, чтобы собрать мусор.) Впрочем, я после этого отметил, что он может работать и более эффективно.
Если потоков несколько, то локальная minor heap у каждого своя. major - одна на всех. При нехватке памяти, она увеличивается на величину, заданную при запуске программы параметром (для разный куч своя константа). Кроме того, есть интерфейс к GC. С его помощью можно настроить его из самой программы.

kokoc88

Если потоков несколько, то локальная minor heap у каждого своя. major - одна на всех. При нехватке памяти, она увеличивается на величину, заданную при запуске программы параметром (для разный куч своя константа). Кроме того, есть интерфейс к GC. С его помощью можно настроить его из самой программы.
Я понял, но ведь никто не отменяет вызовы синхронного GC в данном потоке во время создания объектов. В то время как асинхронный GC может полностью отработать в отдельном потоке. Опять же, увеличение на константу - это не очень хороший подход. Было бы лучше задавать увеличение в процентах.

Dasar

кстати я правильно понимаю, что вот что-то такое компилироваться не будет?

FUNCLASS(double, myfunc, (std::map<int, int> data
{
// код X
}

Dasar

> Как бы ты стал решать данную задачу?
если цель без макросов, даже такое устраивает

class Fun1:FunClass<..>
{
public: FunClass(int x, double y){this->x = x; this->y = y;}
int x;
double y;

public void work
{
}
};
Fun1 fun1(int x, double y)
{
return new Fun1(x, y);
}


ps
просто надо понимать, что устраняя дублирование в данном определении и вводя макросы, мы добавляем дополнительный абстрактный слой (или другими словами: вводим свой новый язык, но при этом не даем никаких инструментов (проверки, отладки, построения общности и т.д.) для работы с этим языком)
соответственно, особенно при командной работе, если вышеприведенное не часто используемая шняга, то лучше обойтись без введения доп. языка, мирясь с дублированием.
если это часто используемая шняга, то поверх вот этого кода делаем макросы или честный язык.

Landstreicher

> кстати я правильно понимаю, что вот что-то такое компилироваться не будет?
> std::map<int, int> data
Если в типе аргумента есть запятая, то, да, не будет. Это тоже пример кривизны (даже не знаю чьей — макросов, шаблонов, типов).
IMHO, то что один и тот же символ используется для множества концептуально разных вещей, например < - оператор меньше, логический сдвиг, запись в поток и ограничитель аргументов шаблона, не есть хорошо.

Landstreicher

> если это часто используемая шняга, то поверх вот этого кода делаем макросы или честный язык.
Вызовы этих макросов генерятся автоматически. Происходит преобразование из одного C++-ного кода в другой С++-ной код.
Если делать по-хорошему, то нужен полноценный парсер, который парсит объявления функций и по ним генерит классы по типу, того как ты написал, без всяких макросов. Парсинг C++ — очень сложная задача, и авторы тулзы не смогли его осилить. В результате было придумано хитроумное (я бы даже сказал хитрожопое) решение с макросами.
В отличие от многих других языков, где средства преобразования кода пишутся легко и непринужденно (те же Lisp, ML, Haskell синтаксис С++ настолько запутан, что даже простые преобразования кода не всегда удается делать нормально и приходится изобретать грязные хаки.
Я видел много случаев, где макросы используются из-за того, что нет нормальных средств парсинга и генерации кода. В связи с этим я не понимаю, почему использование препроцессора — это плохо, и не согласен с лозунгами типа "preprocessor must die!"

Marinavo_0507

и не согласен с лозунгами типа "preprocessor must die!"
они хотели сказать "cpp must die!", но просто не в курсе, что бывают другие препроцессоры
но частично есть правда в этом
если препроцессор плохо интегрирован со средой разработки (то есть, он совсем внешний или наколеночный то бывают всякие неудобства

Dasar

> и не согласен с лозунгами типа "preprocessor must die!"
> синтаксис С++ настолько запутан
это обусловлено следующим
1. цель - упихать в код, как можно больше разных языков (в C++ как минимум 4 языка: язык выражений, процедурный, ООП, мета (шаблоны) + язык препроцессинга)
следствие - смысл одного и того же символа меняется от контекста
2. цель - языки должны по максимуму быть "связаны" (т.е. один язык должен, по максимуму, уметь оперировать элементами из других языков)
следствие: в рамках даже одной строки может происходить смешение чуть ли не всех контекстов, поэтому надо уметь очень четко эти контексты определять
вывод: препроцессинг не умеет определять контекст, и поэтому must die.
ps
если брать C-группу языков, то правильный "препроцессинг" в Nemerle, там он реализован, как прямое преобразование AST-а

Marinavo_0507

если брать C-группу языков, то правильный "препроцессинг" в Nemerle
что там от C, кроме скобок типа {} ?

Helga87

можно построить цепочку языков, начинающуюся с С, где каждый следующий был сделан с активным использованием идей из предыдущего.
Пример такой цепочки: С -> C++ -> Java -> C# -> Nemerle

Marinavo_0507

В C# уже почти ничего нет от C.

Helga87

А в Немерле еще меньше =)
Никто ж не спорит

Ivan8209

>> и не согласен с лозунгами типа "preprocessor must die!"
>> синтаксис С++ настолько запутан
> это обусловлено следующим
> 1. цель - упихать в код, как можно больше разных языков
> (в C++ как минимум 4 языка: язык выражений, процедурный,
> ООП, мета (шаблоны) + язык препроцессинга)
> следствие - смысл одного и того же символа меняется от контекста
Смотрю я на это и удивляюсь, как же это всё смогли сделать
в пределах сотни-двух страниц. Вижу только одно объяснение:
это были не насильники.
> 2. цель - языки должны по максимуму быть "связаны"
> (т.е. один язык должен, по максимуму, уметь оперировать
> элементами из других языков)
> следствие: в рамках даже одной строки может происходить
> смешение чуть ли не всех контекстов, поэтому надо уметь
> очень четко эти контексты определять
> вывод: препроцессинг не умеет определять контекст,
> и поэтому must die.
Объясни, зачем препроцессингу уметь определять контекст?
Наоборот: конструкции должны быть как можно более независимы,
для этого даже умное слово есть --- "ортогональность".
---
"Аллах не ведёт людей неверных."

Landstreicher

это обусловлено следующим
> 1. цель - упихать в код, как можно больше разных языков (в C++ как минимум 4 языка:
Откуда взялась такая странная цель?
IMHO более логично, чтобы в языке были конструкции примерного одного стиля. Зачем делать гибрид ужа с ежом?

Landstreicher

> вывод: препроцессинг не умеет определять контекст, и поэтому must die.
Как ты предлагаешь решать задачи, связанные с построением DSL, кодогенерацией, расширением языков и т.п.?
Введение собственных расширений в язык и их использование в своих программах — широко распространенный и очень удобный метод.

Ivan8209

> Зачем делать гибрид ужа с ежом?
Чтобы получился дикообраз.
---
"Аллах не ведёт людей неверных."

enochka1145

Зачем делать гибрид ужа с ежом?
Потому что у гибридной системы больше шансов выжить. Сегодня C++ - самый успешный язык.
Другой пример - человек. Не хищник и не обезьяна, а непонятный гибрид. И ничего, живём-с.

Ivan8209

> Сегодня C++ - самый успешный язык.
Коболы приходят и уходят.
---
"Аллах не ведёт людей неверных."

kokoc88

Коболы приходят и уходят.
Ты описался. Кохтпы приходят и уходят.

Landstreicher

> Потому что у гибридной системы больше шансов выжить. Сегодня C++ - самый успешный язык.
У системы — да. У системы, состоящей из сбалансированного использования нескольких разных языков. Почему надо делать это в рамках одного языка?

Dasar

> Почему надо делать это в рамках одного языка?
потому что хочется иметь возможность в одной среде в одном файле записать хотя бы что-нибудь такое:

var maxCount = async{ReadMaxCountFromInet};
var items = select id, name, count from DataTable where count > maxCount;
OutputXml(<Data>foreach(var item in items){<Item name='item.name' count='item.count'/>}</Data>);

и совсем не хочется открывать 15 окон в 15 разных средах с 15 разными компиляторами, чтобы написать то же самое.

Ivan8209

>> Почему надо делать это в рамках одного языка?
> потому что хочется иметь возможность в одной среде в одном файле записать
> хотя бы что-нибудь такое:
> var maxCount = async{ReadMaxCountFromInet};
> var items = select id, name, count from DataTable where count > maxCount;
> OutputXml(<Data>foreach(var item in items){<Item name='item.name' count='item.count'/>}</Data>);
> и совсем не хочется открывать 15 окон в 15 разных средах с 15 разными компиляторами,
> чтобы написать то же самое.
Про 15 сред это ты сам придумал, изначально речь шла о двух: низкоуровневой
и высокоуровневой. Даже если этих сред всё-таки полтора десятка, никто не мешает
тебе использовать _одну_ среду и не открывать окна десятками. У меня число
буферов доходит до трёх сотен, и это меня напрягает только при запуске.
А ещё существует noweb.
---
"Narrowness of experience leads to narrowness of imagination."

Dasar

> низкоуровневой и высокоуровневой
т.е. такими языками как:
sql, xml, html, jscript, xslt/xquery ты не пользуешься?

tipnote

>т.е. такими языками как:
>sql, xml, html, jscript, xslt/xquery ты не пользуешься?
Я себе представил мешанину синтаксиса
По-моему, на*й такое счастье. Как и саму идею "все в одном"

Dasar

> По-моему, на*й такое счастье. Как и саму идею "все в одном"
т.е. такой типичный код в web-проекте лучше?

DataTable items = GetTable("select id, name, count from DataTable where count > maxCount");
WriteLine("<table>");
foreach (DataRow itemRow in items)
WriteLine(<tr><td>{0}</td><td>{1}</td></tr>", itemRow["id"], itemRow["name"]);
WriteLine("</table>");

или ты как-то себе по другому представляешь?

Ivan8209

5 и 15 --- совсем разные величины.
---
"Аллах не ведёт людей неверных."

Marinavo_0507

sql, xml, html, jscript, xslt/xquery ты не пользуешься?
А что, их уже тоже встроили в C++?

Helga87

почти все из этого (правда, не в полном виде, а наиболее часто используемые части) будет встроено в C# 3.0 в рамках Linq.

Dasar

а что у нас уже C++ считается быстро развивающимся языком, который быстро реагирует на современные реалии?

tipnote

Имхо, это лажа мешать представление и логику.
Юзай MVC схему
Для представления - шаблоны в отдельных модулях.
Для логики - метаописания данных опять же в отдельных модулях.
Для работы с БД - ORM который смотрится во многих языках не в пример логичнее чем sql запросы. И т.д.

Dasar

> Юзай MVC схему
во-первых, ты сейчас это заявляешь, как теоретик, или как практик?
во-вторых, откуда следует, что использование MVC требует, чтобы описания M, V и C описывались в трех разных файлах в трех разных средах?

tipnote

Во-первых, как практик.
Во-вторых, не следует.
Поэтому мой пост читай так:
1) юзай MVC
2) пиши в отдельных модулях (сразу поясню, что модуль я понимаю в том же смысле что и Python) M, V и C, потому что мне это кажется удобным и логичным.
Не более того.

Dasar

> 2) пиши в отдельных модулях (сразу поясню, что модуль я понимаю в том же смысле что и Python) M, V и C, потому что мне это кажется удобным и логичным
это противоречит XP и дорого.

Dasar

> Во-первых, как практик.
напомню, что основная цель практика - сделать как можно правильнее за как можно дешевле.
если цель - просто сделать как можно правильнее, то это уже пошла наука, а не практика

Landstreicher

> напомню, что основная цель практика - сделать как можно правильнее за как можно дешевле
Поясни, почему разработка в двух файлах дороже, чем разработка того же кода в одном файле.

tipnote

>дорого
1) Модуль в питоне - это отдельный файл.
2) И верстальщик обязан знать твой меганакрученный ЯП или все ж таки только простой язык шаблонов?
3) А поддержка кода с навороченным синтаксисом и перемешанными кусками представления, обработки ввода и бизнес-логики тебе дороже не выйдет?

Landstreicher

> в трех разных файлах в трех разных средах?
Откуда следует, что для того, чтобы редактировать три файла нужны три среды? Разве современные среды не позволяют редактировать сразу несколько файлов?

Ivan8209

> а что у нас уже C++ считается быстро развивающимся языком, который быстро реагирует на современные реалии?
Не знаю, мне, по большому счёту, покласть.
В лиспе есть s-xml и cl-sql, причём в рамках обычного синтаксиса.
---
"Narrowness of experience leads to narrowness of imagination."

tipnote

Йопт.
Не далее как в последнем проекте:
1) Заказчик менял требования к представлению
2) Заказчик менял требования к бизнес-логике
Отдельно и часто.
Каждый раз когда я в своей части проекта отходил от схемы даже в связке C и V я при изменении различных по сложности частей получал неудобство и понимал, почему мне не надо было это мешать.
Поэтому именно как практик для веба я предпочитаю "правильный" MVC.

Dasar

> Разве современные среды не позволяют редактировать сразу несколько файлов?
если уж мы смогли в одну среду запихать поддержку intellisense, refactoring, сборку, отладку нескольких языков, то мне кажется, что уж в один файл все это запихать не проблема.

Dasar

> Поэтому именно как практик для веба я предпочитаю "правильный" MVC.
вот это правильный MVC?

void Execute(string user, int maxCount, Form form)
{
List<Item> items = new List<Item>
foreach (var row in GetTable ("select * From Data where user=@user and count > maxCount", ...
items.Add(Item.From(row;

SimpleGridBind(items, form);
}

void Main
{
Synchronize(form, context => context.user, context => context.maxCount, Execute);
}



Dasar

> 2) И верстальщик обязан знать твой меганакрученный ЯП или все ж таки только простой язык шаблонов?
как из утверждения, что да, в ряде отдельных случаях нам удобнее задавать шаблон формы в виде внешнего модуля следует, что нам всегда необходимо разрабатывать форму в виде трех модулей?

Dasar

> Поясни, почему разработка в двух файлах дороже, чем разработка того же кода в одном файле.
потому что необходимы дополнительные переключения между этими файлами, как при чтении, так и при внесении изменений.
Ps
если эти два файла мы можем одновременно открыть на экране, то почему мы эти два файла не можем слить в один файл?

tipnote

Во-первых, "правильный" стоит в кавычках неслучайно. Слово это взято из твоего комментария:
 
если цель - просто сделать как можно правильнее, то это уже пошла наука, а не практика

И поэтому, как ты можешь заметить, словосочетание несет несколько другой смысл. И уж явно не несет в себе призыв подчиняться "истинному MVC". Равно как я не являюсь "экспертом с мировым именем" в MVC.
Во-вторых, мне не так просто понять твой кусок кода. Но если я понял правильно, то
 
List<Item> items = new List<Item>
foreach (var row in GetTable ("select * From Data where user=@user and count > maxCount", ...
items.Add(Item.From(row;

предпочтительно оформить в методе модели, а не в контроллере, если Execute - это контроллер. Хотя бы потому что оперировать понятиями таблицы - это низкий уровень и по данному куску трудно сразу сказать что он делает в плане логики. Имхо.

Helga87

ваще-то контроллер это задание связей, тут это строчка:
form, context => context.user, context => context.maxCount, Execute

tipnote

Controller
Processes and responds to events, typically user actions, and may invoke changes on the model.
Это и есть сама связь V и M.
Поскольку в Execute происходило управление данными и представлением, то я предположил, что это контроллер.
Указанная тобой строчка мне до конца непонятна (это, кстати, С#?) но предположу что она относится также к контроллеру.

Helga87

это, кстати, С#?

похоже на c# 3.0, но голову на отсечение не дам

Dasar

уточню вопрос
это правильный MVC?

void Execute(string user, int maxCount, Form form)
{
//Model
List<Item> items = new List<Item>
foreach (var row in GetTable ("select * From Data where user=@user and count > maxCount", ...
items.Add(Item.From(row;

//View
SimpleGridBind(items, form);
}

void Main
{
//Controller
Synchronize(form, context => context.user, context => context.maxCount, Execute);
}


этот код необходимо разносить на 3 файла?

Helga87

Это тоже скорее к контроллеру относится
  SimpleGridBind(items, form);  

А к View внутренности метода SimpleGridBind

Dasar

> Поскольку в Execute происходило управление данными и представлением, то я предположил, что это контроллер
в Execute нет управления
в Execute есть:
1. подготовка данных модели на основе входных данных
2. описание View на основе модели

tipnote

>как из утверждения, что да, в ряде отдельных случаях нам удобнее задавать шаблон формы в виде внешнего модуля следует, что нам всегда необходимо разрабатывать форму в виде трех модулей?
Сказать по правде, я бы предпочел НИКОГДА не заниматься версткой, то есть чтобы шаблон ВСЕГДА находился в руках опытного верстальщика, а не программиста б логики, потому что грамотная кроссбраузерная верстка - это достаточно трудоемкая (и совершенно не связанная с б логикой) задача на более или менее сложных интерфейсах.
Но это лирика. Я не считаю неудобство переключения между файлами более неудобным относительно перелистывания кода в поиске, где же тут начинается представление, в котором мне надо передвинуть кнопочку влево. Поэтому я не вижу проблемы.

tipnote

в Execute нет управления
в Execute есть:
1. подготовка данных модели на основе входных данных
2. описание View на основе модели

Можно нагенерить кучу текстов описания об одном и том же.
Я там увидел:
1) Операции с данными (или управление, по-твоему, это только запись?)
2) Операции с представлением (заполнение View данными)
Из чего я сделал вывод, что Execute - контроллер.

Dasar

Могу чуть переписать, чтобы было меньше сомнительных мест

//Model
List<Item> Execute(string user, int maxCount, Form form)
{
List<Item> items = new List<Item>
foreach (var row in GetTable ("select * From Data where user=@user and count > maxCount", ...
items.Add(Item.From(row;
return item;
}

void Main
{
//View
GridForm form = new GridForm;
//Controller
Synchronize(form, context => context.user, context => context.maxCount, Execute, SimpeGridBinder);
}

Helga87

Ага. Знакомая конструкция

Landstreicher

> потому что необходимы дополнительные переключения между этими файлами, как при чтении, так и при
> внесении изменений.
В моем редакторе переключение между окнами делается одной горячей клавишей. После пары дней работы привыкаешь и делаешь это почти рефлекторно.
Ты серьезно считаешь, что необходимость нажимать время от времени одну клавишу может привести к ощутимым затратам (времени, денег, итп)?

nikita270601

потому что необходимы дополнительные переключения между этими файлами, как при чтении, так и при внесении изменений.
А если это будет один файл, он будет очень длинный и искать код будет неудобно. Только не говори про замечательные встроенные в IDE средства навигации, т.к. для них тоже необходимы дополнительные клики мышью и нажатия клавиш.

Dasar

> Ты серьезно считаешь, что необходимость нажимать время от времени одну клавишу может привести к ощутимым затратам (времени, денег, итп)?
я серьезно считаю, что если:
1. этого клика можно избежать, то лучше его избежать.
2. вместо одного файла сделать три всегда можно, обратно в данном случае, неверно.

Marinavo_0507

вместо одного файла сделать три всегда можно, обратно в данном случае, неверно.
почему неверно?
довольно нетрудно придумать мета-синтаксис, объединяющий 3 файла в одном буфере редактирования
и, конечно, проблем с интеграцией этого в среду разработки тоже не будет, если она нормальная
ну, кстати, в ocaml куски кода на других языках встраиваются нетрудно, в этом разделе был пример
в лиспе встроенным препроцессором тоже можно, но надо преобразовывать синтаксис в s-выражения, о чём выше писал контра

tipnote

Ок. Пусть это будет MVC. (Хотя в данный момент контроллер - это скорее весь Main, а вью скрыто в GridForm.)
Но не будем об этом препираться.
Что ты хотел показать этим примером?

Dasar

> Что ты хотел показать этим примером?
что совсем не следует, что M, V и C обязаны быть в разных файлах.

Dasar

> ну, кстати, в ocaml куски кода на других языках встраиваются нетрудно, в этом разделе был пример
и в чем тогда проблема?

tipnote

OMG
Я это еще раньше подтвердил вообще-то:
Во-вторых, не следует
Действительно, спор чертовски пустое занятие.

Ivan8209

> надо преобразовывать синтаксис в s-выражения, о чём выше писал контра
Не надо приписывать мне слов, которых я не говорил.

(define (id x) x)
(define (read-line-chars)
(cdr
(unfold (lambda (ch) (char=? ch #\newline id
(lambda (x) (read-char (current-load-port #\1
(define (read-line)
(list->string (read-line-chars
(define (embed delimiter)
(unfold (lambda (s) (equal? s delimiter id
(lambda (x) (read-line 1

(embed "test")
asdf
xcv
test
(display "done") (newline)


$ guile --use-srfi=1 -s ~/scm/embedding.scm
done
$

---
"Аллах не ведёт людей неверных."

Dasar

чем это поможет при попытке поддержать sql в его родной записи?
тем, что придется писать на lisp-е полноценный парсер?
чем это отличается от C-ишного?:

Execute(Parse("Select * from Data";

Ivan8209

Тем, что разбор будет произведён при загрузке, а не во время исполнения.
---
"Narrowness of experience leads to narrowness of imagination."

Marinavo_0507

Проблема в том, что запутанный синтаксис C++ оправдывают поддержкой нескольких парадигм и подъязыков, в то время как другие языки с более регулярным синтаксисом с этим справляются лучше.

Marinavo_0507

Не преувеличивай. Мне тяжело представить, как надо намудрокодить, чтобы сразу требовался гиг памяти. У меня сейчас сервер CRM работает с более чем 100.000 объектов, пожирает 150 МБ.
В java нужно руками указывать размер кучи (с каким-то значением по умолчанию, которое берётся "исходя из конфигурации системы). Соответственно, для больших задач нужно указывать большой объём, и это, как я думаю (сам не проверял, но видел, как другие жаловались) приведёт к неэффективному использованию памяти, если задаче лишь иногда требуется полный объём кучи, а в остальное время она довольствуется меньшим.

Marinavo_0507

Как раз в Java за счет наличия wrapper-классов (Integer, Long, etc.) порождается огромное количество мелких объектов. По статистике Sun, до 90-95% создаваемых объектов имеют очень малое время жизни, соответственно имеют хорошие шансы умереть в Eden Space.
Не настолько огромное, как в функциональных языках.
Я провёл эксперимент - портировал на Ocaml вjn этот бенчмарк : http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_bench/applet...
На ocaml для построения дерева нужно в 3 раза больше объектов выделять, так как там ссылка не может иметь значение null, соответственно это делается, например, с помощью option, по сути - враппером.
После чего сравнил производительность с java (build Blackdown-1.4.2-02) в двух ситуациях:
1. с дефолтными параметрами аллокатора и GC;
2. с оптимизированными параметрами.
Я бы не мучался с оптимизацией, но java требует указывать размер кучи, и со значением по умолчанию выкидывает OutOfMemory при увеличении размерности задачи.
В п.1 выигрывает Java (если хватает размера кучи) более чем в 2 раза, при этом преимущество обеспечивается большими деревьями, на маленьких лидирует ocaml.
В п.2 оптимизацией параметров GC в ocaml можно достичь ускорения на больших деревьях (за счёт некоторого замедления на маленьких и он выходит в лидеры.
Вывод: обеим реализациям не помешали бы более грамотные эвристики для определения значений параметров.
Java 1.5 и 1.6 не смотрел - пока лень устанавливать. Может, кто работает с несколькими версиями, сравнит производительность на этом бенчмарке?

kokoc88

В java нужно руками указывать размер кучи (с каким-то значением по умолчанию, которое берётся "исходя из конфигурации системы). Соответственно, для больших задач нужно указывать большой объём, и это, как я думаю (сам не проверял, но видел, как другие жаловались) приведёт к неэффективному использованию памяти, если задаче лишь иногда требуется полный объём кучи, а в остальное время она довольствуется меньшим.
Ей надо указать минимум и максимум. Скорее, проблема в максимуме. В твоём случае полный объём будет равен максимуму, а память для "довольствуется меньшим" как минимум. Может быть, есть какие-то проблемы с количеством вызовов GC.

Hastya

Настройки GC по умолчанию, конечно?

Marinavo_0507

Как-то там непросто с этими настройками, я не сообразил, куда крутить.

Hastya

Да, весьма непросто, учитывая, что можно включать несколько разных алгоритмов

Marinavo_0507

Там все алгоритмы, кроме дефолтного, странноваты, судя по описанию.
Оставить комментарий
Имя или ник:
Комментарий: