LINUX.ORG.RU
ФорумTalks

Cудьба Mono


0

5

Мигель перешел в стан врага и вещает о «мертвом мертвейшем линуксе».

Mono for Android - минимум 300$. Mono for iOS - минимум 300$. С леденящим душу страхом жду Mono for Lin/Win/Mac - минимум 300$ :)

Моно на линуксе рип-рип? Или все это ерунда, всё будет хорошо и замечательно?

Перемещено mono из development

★★★★☆
Ответ на: комментарий от drBatty

Ты уже можешь перезагружать operator new/operator delete, и потому можешь реализовывать в плюсах _любые_ стратегии управления памяти.

Вранье. Неплоскую память типо как в win16 или 32-битовые интерфейсы дающие доступ к памяти сверх 2Гб ты через operator new/delete не заюзаешь.

Absurd ★★★
()
Ответ на: комментарий от Absurd

Вранье. Неплоскую память типо как в win16 или 32-битовые интерфейсы дающие доступ к памяти сверх 2Гб ты через operator new/delete не заюзаешь.

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

drBatty ★★
()
Ответ на: комментарий от Absurd

Неплоскую память типо как в win16 или 32-битовые интерфейсы дающие доступ к памяти сверх 2Гб ты через operator new/delete не заюзаешь.

И почему же? Адресную арифметику использовать не получится, а объекты памяти - вполне.

tailgunner ★★★★★
()
Ответ на: комментарий от drBatty

Вранье. Неплоскую память типо как в win16 или 32-битовые интерфейсы дающие доступ к памяти сверх 2Гб ты через operator new/delete не заюзаешь.

Т.ч. свои интерфейсы и прочие костыли можешь затолкать обратно. Мне они не нужны.

Нкто тебя не спрашивает что тебе нужно. Есть практическая необходимость заюзать интерфейс, мапящий страницы по требованию. Все, С++ в ауте, юзаем POD-структуры.

Absurd ★★★
()
Ответ на: комментарий от tailgunner

И почему же? Адресную арифметику использовать не получится, а объекты памяти - вполне.

Мы уже говорили на эту тему. В win16 блоки памяти идентифицировались не указателем, а хендлом. Чтобы получить указатель и с ними дальше работать надо было вызвать lock(). После окончания надо было вызвать unlock() чтобы блок памяти мог перемещаться и уйти в своп при необходимости. Адреса живых С++-ных объектов в функции манипулирующие блоками памяти передавать нельзя.

Absurd ★★★
()
Ответ на: комментарий от Absurd

В win16 блоки памяти идентифицировались не указателем, а хендлом. Чтобы получить указатель и с ними дальше работать надо было вызвать lock().

И почему это нельзя сделать через умный уеказатель?

Адреса живых С++-ных объектов в функции манипулирующие блоками памяти передавать нельзя.

Можно, просто нужно понимать последствия. Кстати, какое это имеет отношение к твоей фразе:

Absurd> Неплоскую память типо как в win16 или 32-битовые интерфейсы дающие доступ к памяти сверх 2Гб ты через operator new/delete не заюзаешь.

tailgunner ★★★★★
()
Ответ на: комментарий от Absurd

Нкто тебя не спрашивает что тебе нужно. Есть практическая необходимость заюзать интерфейс, мапящий страницы по требованию. Все, С++ в ауте, юзаем POD-структуры.

почему «в ауте»? Самый простой вариант - перезагружаем new, и делаем так, что-бы он выдавал некий уникальный дескриптор объекта. Вот и всё. А всю хитрую реализацию прячем в этот наш new. Хоть win16, хоть Linux64. Если есть желание и необходимость - можешь хоть распределённую «память» таким образом сделать, на дисках 100500 серверов.

drBatty ★★
()
Ответ на: комментарий от drBatty

Самый простой вариант - перезагружаем new, и делаем так, что-бы он выдавал некий уникальный дескриптор объекта.

Похоже, Абсурдег намекает на то, что из new можно вернуть только адрес, но не дескриптор. Впрочем, это вполне можно обойти для случая мапинга по запросу.

tailgunner ★★★★★
()
Ответ на: комментарий от Absurd

Мы уже говорили на эту тему. В win16 блоки памяти идентифицировались не указателем, а хендлом. Чтобы получить указатель и с ними дальше работать надо было вызвать lock(). После окончания надо было вызвать unlock() чтобы блок памяти мог перемещаться и уйти в своп при необходимости. Адреса живых С++-ных объектов в функции манипулирующие блоками памяти передавать нельзя.

повторяю - оберни свой хендл в «умный указатель», и пользуйся им как обычно.

drBatty ★★
()
Ответ на: комментарий от tailgunner

Похоже, Абсурдег намекает на то, что из new можно вернуть только адрес, но не дескриптор.

можно вернуть объект, который при разименовании прикидывается указателем на нужный нам объект с помощью перезагрузки operator->(). Таким образом мы получаем «указатель», который ведёт себя как обычный указатель, и тем не менее, указателем НЕ является, а имеет дополнительный функционал, который и даёт возможность организовать сборку мусора и/или что угодно.

drBatty ★★
()
Ответ на: комментарий от drBatty

из new можно вернуть только адрес, но не дескриптор.

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

Видно, я что-то упустил из последних лет развития Си++. Можешь дать пример кода, где из new возвращается не указатель?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Видно, я что-то упустил из последних лет развития Си++. Можешь дать пример кода, где из new возвращается не указатель?

ты не понял - я предлагаю возвращать указатель на специальный объект, который ведёт себя как указатель. И кроме того, я предлагаю запретить использовать данный класс иначе, чем через наш «указатель».

drBatty ★★
()
Ответ на: комментарий от drBatty

ты не понял

Так уж ты объясняешь.

я предлагаю возвращать указатель на специальный объект

т.е. new Foo() возвращает не Foo *, а FooPtr *? Не подходит, ибо на указателе нельзя перегрузить operator->. Т.е.

Foo *f = new Foo();
f->m(); // так нельзя - используется обычный operator->

Нужно примерно так:

Foo *f = new Foo(); // мапит память и запоминает указатель в глобальной таблице

f->m();

delete foo; // убирает указатель из глобальной таблицы и анмапит память
tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Можно, просто нужно понимать последствия.

С точки зрения стандарта если ты сделаешь lock(), создашь там объект, и вызовешь unlock(), то после следующего lock() объект будет невалиден если окажется по другому адресу. Если надо его как-то подвинуть в памяти, то нужно использовать placement new с конструктором копирования, про которые типовое сишное API ничего не знает.

Неплоскую память типо как в win16 или 32-битовые интерфейсы дающие доступ к памяти сверх 2Гб ты через operator new/delete не заюзаешь.

Такое и имеет.

Absurd ★★★
()
Ответ на: комментарий от Absurd

Если надо его как-то подвинуть в памяти, то нужно использовать placement new с конструктором копирования, про которые типовое сишное API ничего не знает.

про которые типовое сишное API ничего не знает.

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

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

давно с тобой не разговаривал, забыл, сколь ты любишь соскакивать с темы.

Нету никакого соскока. Разговор шел о возможностях которые дает перегрузка operator new. По стандарту operator new должен возвращать указатель, хендл вернуть он не имеет права. Если же он получит хендл, залочит кусок памяти по хендлу и вернет указатель, то хендл будет потерян. Следовательно, нужную логику на operator new реализовать невозможно, чтд. Уводом разговора с сторону было твое упоминание смарт-указателей. О смарт-указателях речь не шла, речь в ветке шла о перегрузке operator new. Я ясно выражаюсь?

Absurd ★★★
()
Ответ на: комментарий от Absurd

давно с тобой не разговаривал, забыл, сколь ты любишь соскакивать с темы.

Нету никакого соскока.

Еще бы ты признался.

Разговор шел о возможностях которые дает перегрузка operator new.

...после чего ты привел в пример сегментированную модель памяти Win16, которая ломает _абстрактную машину Си_, и по привычке полил Си++.

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

А ты не теряй его.

О смарт-указателях речь не шла, речь в ветке шла о перегрузке operator new. Я ясно выражаюсь?

Распределять память в сегментах Win16 можно с помощью оператора new. Я ясно выражаюсь?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

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

А ты не теряй его.

Стандарт требует чтобы operator new возвращал void*. Какие-то обертки вокруг хендлов блока или сами хендлы оттуда возвращать нельзя.

Распределять память в сегментах Win16 можно с помощью оператора new.

Единственный прямой способ - явно выделить блок памяти нужного размера при помощи внешнего API, а потом разместить в ней объект при помощи placement new. Потом вызвать деструктор явно и удалить блок памяти при помощи внешнего API. Прямого способа скрыть эти телодвижения от клиента кода здесь не существует.

Absurd ★★★
()
Ответ на: комментарий от Absurd

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

А ты не теряй его.

Стандарт требует чтобы operator new возвращал void*. Какие-то обертки вокруг хендлов блока или сами хендлы оттуда возвращать нельзя.

Сделай глобальную таблицу, отображающую хэндл в void *, возвращай void *, и в delete находи хэндл и удаляй его. Такая очевидная мысль тебе в голову не приходила?

Единственный прямой способ - явно выделить блок памяти нужного размера при помощи внешнего API, а потом разместить в ней объект при помощи placement new.

И это тоже работа с «неплоской памятью» через new,

Прямого способа скрыть эти телодвижения от клиента кода здесь не существует.

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

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Сделай глобальную таблицу, отображающую хэндл в void *, возвращай void *, и в delete находи хэндл и удаляй его. Такая очевидная мысль тебе в голову не приходила?

Костыль среди океана плюсовых костылей. BTW, я видимо не такой говнокодер как ты, поэтому мне первой на ум пришла мысль как его отыскивать за атомарное время без привлечения глобальных структур. Надо выделить sizeof(HANDLE) + sizeof(T) и разместить этот хендл перед блоком. Вернуть указатель указывающий на первый байт после HANDLE.

Единственный прямой способ - явно выделить блок памяти нужного размера при помощи внешнего API, а потом разместить в ней объект при помощи placement new.

И это тоже работа с «неплоской памятью» через new,

Речь в ветке идет о практической пользе от возможности перегрузки operator new в пользовательском типе. А placement new это глобальный оператор.

Absurd ★★★
()
Ответ на: комментарий от Absurd

Нету никакого соскока. Разговор шел о возможностях которые дает перегрузка operator new. По стандарту operator new должен возвращать указатель, хендл вернуть он не имеет права. Если же он получит хендл, залочит кусок памяти по хендлу и вернет указатель, то хендл будет потерян. Следовательно, нужную логику на operator new реализовать невозможно, чтд. Уводом разговора с сторону было твое упоминание смарт-указателей. О смарт-указателях речь не шла, речь в ветке шла о перегрузке operator new. Я ясно выражаюсь?

не ври. Изначально речь шла о смарт-указателях И презагрузке new.

одно без другого не имеет смысла в C++.

drBatty ★★
()
Ответ на: комментарий от drBatty

одно без другого не имеет смысла в C++.

Обычно в качестве достоинства выставляют ортогональность. А у плюсофагов вон оно как.

Absurd ★★★
()
Ответ на: комментарий от Absurd

одно без другого не имеет смысла в C++.

Обычно в качестве достоинства выставляют ортогональность. А у плюсофагов вон оно как.

как «так»? В других ЯП дополнительная функциональность гвоздями прибита к операции «равно» (копирование), а в C++ этого нет. И это хорошо, ибо нет оверхеда в большинстве случаев, когда никакие сборщики мусора не нужны. А когда нужны - можно это реализовать.

drBatty ★★
()
Ответ на: комментарий от drBatty

Обычно в качестве достоинства выставляют ортогональность. А у плюсофагов вон оно как.

В других ЯП дополнительная функциональность гвоздями прибита к операции «равно» (копирование), а в C++ этого нет.

А что там в operator= можно такого сделать? Сконструировать временный объект, а потом обменять pimpl-ы? Дык в других языках объекты и являются своими pimpl-ами.

Absurd ★★★
()
Ответ на: комментарий от Absurd

А что там в operator= можно такого сделать? Сконструировать временный объект

зачем? Например мне тут доказывали, что gc в рамках C++ невозможен, доказательство сводилось к коду, в котором как раз и вызывалась функция копирования «равно». При этом, для доказывающего было очевидным, что = просто тупо копирует, а значит сборщик мусора не знает, что у объекта появилась копия. И таким образом, gc не сможет этот мусор собрать. Но на самом деле вызывался конструктор копирования, который и имеет возможность сообщить сборщику о факте появления новой копии. В самом примитивном варианте можно увеличить счётчик ссылок на 1, и вообще ничего не копировать, а просто использовать старый объект.

drBatty ★★
()
Ответ на: комментарий от drBatty

В самом примитивном варианте можно увеличить счётчик ссылок на 1, и вообще ничего не копировать, а просто использовать старый объект.

Инфраструктурного кода который не относится к решаемой программистом проблеме существовать не должно.

Absurd ★★★
()
Ответ на: комментарий от Absurd

Инфраструктурного кода который не относится к решаемой программистом проблеме существовать не должно.

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

А код он всё равно _будет_, и мне проще иметь возможность его менять.

drBatty ★★
()
Ответ на: комментарий от drBatty

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

Когда дело дойдет до того что заказчик пожалуется на то что твой сервер падает в среднем раз в два часа, заинтересоваться таки придется.

А код он всё равно _будет_, и мне проще иметь возможность его менять.

Ты просто лентяй и тебе влом разбираться в больших сложных фреймворках.

Absurd ★★★
()
Ответ на: комментарий от Absurd

Когда дело дойдет до того что заказчик пожалуется на то что твой сервер падает в среднем раз в два часа, заинтересоваться таки придется.

с чего он будет падать-то? пойми, в C++ технологию сборки мусора можно применять _локально_, в пределах одного какого-то класса, которому это _действительно_ нужно. В большинстве случаев необходимости в gc нет никакой. Вот в C++ её и не применяют (в 95% классов). Потому, если уж обнаружился какой-то глюк gc, то его можно с лёгкостью локализовать и исправить. В отличие от...

Ты просто лентяй и тебе влом разбираться в больших сложных фреймворках.

...и это тоже.

drBatty ★★
()
Ответ на: комментарий от drBatty

с чего он будет падать-то? пойми, в C++ технологию сборки мусора можно применять _локально_, в пределах одного какого-то класса, которому это _действительно_ нужно.

Данный подход поощряет написание чисто синхронного кода, где ресурсы всегда чистит вызывающий после того как вызываемый отработал.

Ты просто лентяй и тебе влом разбираться в больших сложных фреймворках.

...и это тоже.

Ну я конечно понимаю что легче заниматься решением уже решенных проблем чем нерешенных.

Absurd ★★★
()
Ответ на: комментарий от Absurd

Данный подход поощряет написание чисто синхронного кода, где ресурсы всегда чистит вызывающий после того как вызываемый отработал.

что в этом плохого?

Ну я конечно понимаю что легче заниматься решением уже решенных проблем чем нерешенных.

дело не в этом. Знаешь, почему до сих пор не сделали автомобиль для всех? Просто потому, что потребности у всех разные. Кому-то нужен порше, кому-то москвич, а кому-то камаз. И именно по этому до сих пор не придумали идеальную стратегию распределения памяти - она в 95% случаев будет НЕ идеальной, и в 50% случаев - унылым говном.

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

Вот возьми тот же алгоритм Бейкера, который здесь обсуждался. Он отлично работает (хотя и отъедает вдвое больше памяти чем нужно) пока памяти достаточно. Но как только программа подходит к пределу, этот ваш stop'n'copy вешает вашу программу намертво. Не, я согласен, это тоже решение. Но согласись, не всегда оно допустимо.

В итоге, я не смогу написать даже программу управления сливным бачком в унитазе(на сишарпе) - надо СРОЧНО клапан открывать, а оно мне тут мусор собирает. Я понимаю, такое будет происходить не часто, но тем не менее это будет не слишком-то и приятно. Такие дела.

drBatty ★★
()
Ответ на: комментарий от drBatty

Данный подход поощряет написание чисто синхронного кода, где ресурсы всегда чистит вызывающий после того как вызываемый отработал.

что в этом плохого?

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

Знаешь, почему до сих пор не сделали автомобиль для всех? Просто потому, что потребности у всех разные. Кому-то нужен порше, кому-то москвич, а кому-то камаз. И именно по этому до сих пор не придумали идеальную стратегию распределения памяти - она в 95% случаев будет НЕ идеальной, и в 50% случаев - унылым говном.

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

Absurd ★★★
()
Ответ на: комментарий от Absurd

Ну то есть ты в универсальной стратегии управления ходом выполнения не видишь ничего плохого, а в универсальной стратегии управления памятью - видишь.

синхронную модель мне никто не навязывает, он только «поощряется», и это хорошо, ибо синхронная модель тупо проще, а стало быть асинхронную следует применять лишь тогда, когда нужно. А вот управление памятью в сишарпе такое, какое есть. И ничего я с ним поделать не могу. Разве что сишарп перекомпиллирую. Но это невозможно, ибо сырцов нет, да если они и были, то тут ведь пишут, что сишарп докомпилливается у клиента...

Хотя есть асинхронная модель где определить владельца данных передаваемых от обработчика к обработчику однозначно бывает нелегко.

я знаю. Именно в таких случаях и есть смысл применять сборку мусора. Однако, накой эта сборка например для выделения памяти под строчку, которую никто, кроме этого кода всё равно не будет использовать, да и не сможет, даже если захочет? А таких строчек 99% ваще-то.

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

Ой, да ладно!

И где я к этому призывал? Лично я не вижу ничего плохого например в STL, и прочих библиотеках (в т.ч. и коммерческих), вот только я также не вижу никакой необходимости прибивать гвоздями этот функционал к самому языку. К примеру мне и в голову не придёт писать собственный std::string - именно по озвученной тобой причине. Кроме того, если я уж сподобился юзать например Qt, то я буду юзать также и QString, а не что-либо другое. Но на кой хрен мне сдался String в самом ЯП?? Ну а свой класс(шаблон) my_string я если и буду писать, то только в том случае, если:

1. у меня какие-то особые строки, СОВСЕМ не такие, на которые заточен std::string

2. и кроме того, работа с этими строками занимает ЗНАЧИТЕЛЬНУЮ часть ресурсов.

Если хоть один из этих пунктов не выполнен, я даже думать не стану о своём велосипеде.

drBatty ★★
()
Ответ на: комментарий от drBatty

синхронную модель мне никто не навязывает, он только «поощряется», и это хорошо, ибо синхронная модель тупо проще, а стало быть асинхронную следует применять лишь тогда, когда нужно

Вот написание гуя это прямо такая вот редкая задача которая редко нужна, например. И поручают ее обычно только выпускникам Berkley и MIT.

А вот управление памятью в сишарпе такое, какое есть. И ничего я с ним поделать не могу.

Выдели себе для своих CERN-овских рассчетов огромный массив и размести его в статическом scope. GC его трогать не будет.

1) у меня какие-то особые строки, СОВСЕМ не такие, на которые заточен std::string. 2) и кроме того, работа с этими строками занимает ЗНАЧИТЕЛЬНУЮ часть ресурсов.

Ты конечно же можешь привести примеры таких задач? Или это абстрактные построения?

Absurd ★★★
()
Ответ на: комментарий от Absurd

Вот написание гуя это прямо такая вот редкая задача которая редко нужна, например. И поручают ее обычно только выпускникам Berkley и MIT.

а если мне нужен гуй, я его не стану писать. Зачем? Мало что-ли тулкитов на любой вкус? А уж прицепить свою функцию к чекбоксу я как-нибудь осилю.

Выдели себе для своих CERN-овских рассчетов огромный массив и размести его в статическом scope. GC его трогать не будет.

открой наконец Кнута, и узнай о разряжённых матрицах. Причём без всяких GC.Искусство программирования, том 1, 2.2.6

Ну и освежи для себя 2.3.5 оттуда-же, что-бы не говорить ерунды (кстати, Кнут на ассемблере захерачил GC, и ничего - работает даже. Так то)

drBatty ★★
()
Ответ на: комментарий от Absurd

Ты конечно же можешь привести примеры таких задач? Или это абстрактные построения?

да что-то в голову не приходит ничего интересного. Я же говорю, IRL достаточно STL или средств тулкита. Когда-то давно пришлось делать...

Про сборщик мусора я уже говорил - мне как-то понадобился вырожденный сборщик, который ничего не собирает. Но удаление там тоже таки было (просто память не освобождалась, типа как в tar --delete или CD-R).

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.