LINUX.ORG.RU

Ответ на: комментарий от next_time

тождество - это абсолютное соответствие одной сущности другой, поэтому 0 типа чар не тождественнем 0 типа инт

внутри подмножества более узкие рамки. Потому, если записать в rax char=0, и в rdx int=0, то содержимое rdx,rax будет тождественно равно. Отличие есть, но оно осталось ЗА рамками подмножества, и внутри подмножества мы имеем тождество.

Кстати, нулевые константы в сишечки тоже тождественно равны, если это не NULL.

emulek
()
Ответ на: комментарий от slackwarrior

Тащем-та абсолютное тождество - это тавтология :)

тащем-то нет. Всё зависит от того, что мы понимаем под смыслом значка ∀.

emulek
()
Ответ на: комментарий от next_time

тождество - это абсолютное соответствие одной сущности другой, поэтому 0 типа чар не тождественнем 0 типа инт

с чего ты взял, что константа 0x00 имеет тип char?

emulek
()
Ответ на: комментарий от next_time

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

хорошо документированные инструкции по наступанию на грабли, ок

смирись с тем, что ты неосилятор.

echo $x++ + ++$x;

ССЗБ

а что не так в этом коде? Ответ обоснуй.

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

смирись с тем, что ты неосилятор.

неосилятор наступания на грабли? безусловно

а что не так в этом коде?

то, что он тяжело читается, нельзя так код писать

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

неосилятор наступания на грабли? безусловно

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

то, что он тяжело читается, нельзя так код писать

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

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

когда наступаешь на грабли какого-то питона?

потому, что мне неясно, зачем нужен питон, когда есть С# ?

Если тебе нужен хоть какой-то код, и есть только обезьяны, то ничего не поделаешь...

от таких ситуаций следует воздерживаться

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

Ты знаешь что делает strcpy в C? После strcpy(dest,src) мусор не появится.

anonymous
()
Ответ на: комментарий от next_time

1. Поищи на форуме тут кот-то портировал программу на ахитектуру с 16-битным char. И не надо выдумывать про несоответствие стандарту компиляторов под архитектуры, про которые не знаешь.

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

Поищи на форуме тут кот-то

не собираюсь. пруфлинк в студию

под архитектуры, про которые не знаешь.

так приведите пример такой архитектуры

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

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

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

даже если придумать умные указатели

Боже...

еще можно хранить отдельно список ссылок, лажащих на стеке

тред не читай, сразу отвечай

Этот уровень аналитики уже даже не диванный, он раскладушечный.

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

Проблема в том, что для mark & sweep нужно не только знать какие объекты выделены под сборку (это можно было бы решить просто помещая все собираемые объекты в отдельную кучу, например), но и какие объекты в настоящий момент ни в коем случае собирать нельзя (их я собственно и называл корневыми). Обычно это глобальные объекты и объекты ссылки на которых есть на стеке. Все корневые объекты по умолчанию доступны. Затем GC рекурсивно помечает доступными все объекты на которые есть ссылки из уже доступных объектов. После все не помеченные объекты он освобождает. Так вот в плюсах основная проблема это определение списка корневых объектов.

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

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

дальнейшую чушь не читал.

emulek
()
Ответ на: комментарий от KblCb

Обычно это глобальные объекты и объекты ссылки на которых есть на стеке. <..> Так вот в плюсах основная проблема это определение списка корневых объектов.

так вот: не делай глобальных объектов и объектов на стеке. Если ты их сделал внутри class::new — ты ССЗБ.

Если не делал, то искомый список пуст.

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

Если не делал, то искомый список пуст.

Этот список необходим для работы сборщика мусора. Без него он банально не может определить какие объекты надо собирать, а какие — нет.

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

ну так предложи алгоритм. чего зря болтаешь? я делал для с++ сборщики с различными стратегиями. полноценно сделать это невозможно. полноценному сборщику нужна метаинформация, карта ссылок объекта, карта рутовых объектов. в jvm и clr этим занимаются компилятор и jit.

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

уже всё давно предложил в этом треде, и не свой велосипед, а готовое решение, для «тред не читай - сразу отвечай» повторяться не стану

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

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

anonymous
()
Ответ на: комментарий от KblCb

Вы читаете или нет то, что вам отвечают? Сборщик мусора и так знает, что собирать, т.к. то что нужно собрать было выделено оператором new.

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

boehm не является полноценным сборщиком.кроме того, он иногда принимает за объекты то, что ими не являеься.

anonymous
()
Ответ на: комментарий от next_time

но он не знает, что собирать пока не надо.

anonymous
()
Ответ на: комментарий от KblCb

Если не делал, то искомый список пуст.

Этот список необходим для работы сборщика мусора. Без него он банально не может определить какие объекты надо собирать, а какие — нет.

список есть, и он пуст. Т.е. когда написано

X = Y;
То это означает, что старое содержимое X НЕ в стеке, и НЕ глобальное. А оно в куче, причём является мусором, если больше его никто не использует.

emulek
()
Ответ на: комментарий от anonymous

я делал для с++ сборщики с различными стратегиями. полноценно сделать это невозможно. полноценному сборщику нужна метаинформация, карта ссылок объекта, карта рутовых объектов. в jvm и clr этим занимаются компилятор и jit.

ты лучше расскажи, почему и что у тебя не получилось в C++?

Лично мне твои затруднения непонятны.

emulek
()
Ответ на: комментарий от anonymous

на стеке ссылки на объекты, а не сами объекты.

это не важно.

GC работает НЕ со ссылками, и НЕ с объектами, а с СОДЕРЖИМЫМ объектов. Ну например у тебя есть объект string, а ВНУТРИ него указатель на строку char *string_ptr;. Вот GC работает с string_ptr, а он ВСЕГДА в куче, как в твоей яве. Ты его просто НЕ МОЖЕШЬ сделать не в куче, ибо он private, и доступ к нему ТОЛЬКО через методы.

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

причём является мусором, если больше его никто не использует.

Как определить, используют его или нет?

anonymous
()
Ответ на: комментарий от emulek

ты лучше расскажи, почему и что у тебя не получилось в C++?

Я не он, но думаю, что трудность тут как раз в построении карты объектов. В языках с нормальным рантаймом этим занимается jit по той метаинформации, что оставил для него компилятор. В С++ этого всего нет(может быть в llvm разве что, в libjit вроде не видел).

anonymous
()
Ответ на: комментарий от emulek

Ну например у тебя есть объект string, а ВНУТРИ него указатель на строку char *string_ptr;. Вот GC работает с string_ptr, а он ВСЕГДА в куче, как в твоей яве. Ты его просто НЕ МОЖЕШЬ сделать не в куче, ибо он private, и доступ к нему ТОЛЬКО через методы.

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

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

Как это пуст? Это список не мусора, а список доступных объектов.

для тех кто в танке: ВСЕ объекты в списке GC лежат в куче.

Разве сложно распарсить это простое предложение?

причём является мусором, если больше его никто не использует.

Как определить, используют его или нет?

в данном случае

X = Y;
тем же самым operator=(). Вот тут оно не только отправляет в мусор (потенциальный) старое содержимое X, но и ещё кроме того, определяет, что содержимое Y используется не только самим Y, но и теперь X. Потому, если дальше
Y = Z;
то GC, когда запустится, НЕ удалит старое Y, ибо оно используется ещё и X.

В самом простом случае достаточно счётчика ссылок, который для Y в начале равен 1, а вот после

X = Y;
будет равен 2.

Ну а для X, после этой же операции, счётчик ссылок декрементируется.

ВАЖНО: это ОДНА ИЗ реализаций, самая простая, на пальцах. Можно юзать любую иную тактику и/или стратегию.

emulek
()
Ответ на: комментарий от anonymous

Я не он, но думаю, что трудность тут как раз в построении карты объектов. В языках с нормальным рантаймом этим занимается jit по той метаинформации, что оставил для него компилятор. В С++ этого всего нет

Верно. В C++ искороппки имеется тупой operator=(), который тупо побитно копирует весь объект.

Но это вовсе не значит, что этот operator=() нельзя перезагрузить. Можно. И нужно. Даже если ты его не используешь.

emulek
()
Ответ на: комментарий от anonymous

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

они не просто в куче, они вообще ЗАКРЫТЫ. Ты не можешь на них влиять напрямую. Можешь только косвенно, например через метод operator=(). Вот этот-то метод и сохраняет информацию о том, что есть мусор, а что не мусор.

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

Основная идея сборщика мусора в том, чтобы делегировать поиск и удаление невостребованных объектов отдельному самостоятельному «модулю», который никак не взаимодействует с логикой работы самого приложения и является частью исполняющей среды. Основная проблема сборщика мусора - поиск объектов, которые доступны(или, наоборот, недоступны). Вот вас тут и спрашивают, каким вы видите алгоритм поиска доступных объектов в сборщике для С++. Boehm ищет в «памяти»(в стеке каждого потока, в регистрах, в статической памяти, в куче, в собственной куче) слова, значение которых совпадает с диапазоном адресов выделенных boehm'ом объектов. И помечает эти объекты как используемые. Остальные объекты в своей куче считает мусором. Это работает, но имеет ряд существенных недостатков. Во-первых, мы можем принять за ссылку на объект обычно число, значение которого совпадает с указателем. Во-вторых, мы не имеем возможности перемещать объекты в куче(а такое перемещение позволяет существенно ускорить выделение памяти). В-третьих, никаких тебе поколений и каких-либо других плюшек полноценного(отделенного от логики приложения) сборщика мусора.

Для реализации этого безобразия на С++, нам потребуется руками составлять карту gc, что скажется на ограничении классов объектов, которые можно будет размещать в такой куче, и/или на производительности кода(т.к. в отличие от jit нам придется строить карту каждый раз, т.к. мемоизация не будет корректной).

anonymous
()
Ответ на: комментарий от emulek

Так это не сборка мусора, а обычное ручное управление памятью. Как сейчас в С++ и сделано. Просто в отличие от голого Си, в С++ есть RAII, что упрощает построение такого кода.

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

Вот вас тут и спрашивают, каким вы видите алгоритм поиска доступных объектов в сборщике для С++.

для тех кто в танке: ЛЮБЫЕ. Хотите как в яве? Ну делайте, в чём проблема-то? Что вам мешает?

Boehm ищет в «памяти»(в стеке каждого потока, в регистрах, в статической памяти, в куче, в собственной куче)

у вас на нём Света с Климом сошлась? Что, если кто-то сделал так, то это доказывает, что иначе — никак?

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

с моим подходом

1. Не можем. Ибо информация об указателе хранится внутри класса отдельно от указателя.

2. Мы можем перемещать объекты в куче, как нам заблагорассудится. Точнее — сами объекты останутся, но их содержимое будет прыгать куда угодно. Да, при этом счётчики ссылок уже не подходят.

3. Вам доступны любые плюшки, какие вы пожелаете.

Для реализации этого безобразия на С++, нам потребуется руками составлять карту gc, что скажется на ограничении классов объектов, которые можно будет размещать в такой куче, и/или на производительности кода(т.к. в отличие от jit нам придется строить карту каждый раз, т.к. мемоизация не будет корректной).

накладные расходы будут ровно такими же, как и в любой другой реализации GC. Если ты с этим не согласен — обосновывай. Расскажи, как твоя мемоизация происходит у тебя, и почему у тебя не получилось сделать это в C++. Я расскажу, в чём ты ошибаешься, и как это исправить.

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

для тех кто в танке: ЛЮБЫЕ. Хотите как в яве? Ну делайте, в чём проблема-то? Что вам мешает?

Отсутствие метаинформации о типах объектов, отсутствие карты полей-ссылок объекта.

с моим подходом

Твой подход - это ручное управление памятью.

накладные расходы будут ровно такими же, как и в любой другой реализации GC. Если ты с этим не согласен — обосновывай. Расскажи, как твоя мемоизация происходит у тебя, и почему у тебя не получилось сделать это в C++. Я расскажу, в чём ты ошибаешься, и как это исправить.

Обычная jit'овая мемоизация. В С++ она невозможно для GC, поскольку у тебя будет машкод, а не интерпретируемый байткод. Ты не сможешь корректно запомнить карту для функции(например), т.к. при следующем исполнении данной функции, карта может быть совсем другой и ты не можешь это определить, для этого тебе придется интерпретировать машкод.

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

Так это не сборка мусора, а обычное ручное управление памятью.

а в сборке мусора разве есть какая-то необычная магия? Такая, что в принципе не реализуема в рамках C++?

Можешь пример магии в студию? Да, вот такой НЕРУКОТВОРНОЙ, а некой БОЖЕСТВЕННОЙ. А то у меня в C++ да, всё вручную...

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

а в сборке мусора разве есть какая-то необычная магия? Такая, что в принципе не реализуема в рамках C++?

Так сама сборка и нереализуема. Если только для llvm не написать свой компилятор с расширением для работы с GC.

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

Отсутствие метаинформации о типах объектов, отсутствие карты полей-ссылок объекта.

сделай поля с метаинформацией, и сделай карту. Кто тебе запрещает?

Твой подход - это ручное управление памятью.

безусловно. Не боги горшки обжигают. И «само по себе» ничего не происходит. Во всяком случае в CS.

Обычная jit'овая мемоизация. В С++ она невозможно для GC, поскольку у тебя будет машкод, а не интерпретируемый байткод.

1. почему «невозможна»?

2. что мне мешает сделать байткод, если это так уж НАДО?

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

можно на примере, с несложной функцией?

emulek
()
Ответ на: комментарий от anonymous

Так сама сборка и нереализуема. Если только для llvm не написать свой компилятор с расширением для работы с GC.

ясно. Я так и думал. Значит — магия.

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

Можешь пример магии в студию?

Ну вот какой-то набросок:

class A
{
    // ...
}

class B
{
    void set_x(ref A x)
    {
        m_x = x;
    }

    ref A get_x()
    {
        return m_x;
    }
private ref A m_x
}

//...

void set_b_x(ref B b1, ref B b2)
{
    b1.set_x(b2.get_x);
}
//...


ref B make_my_b()
{
    ref A a = new A;
    ref B b1 = new B;
    ref B b2 = new B;

// ...

    b2.set_x(a);
    set_b_x(b1, b2);
//...
    return b1;
}

Тут даже циклических ссылок нет.

anonymous
()
Ответ на: комментарий от emulek

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

anonymous
()
Ответ на: комментарий от emulek

сделай поля с метаинформацией, и сделай карту. Кто тебе запрещает?

Я могу это написать для рантайма, но я не могу заставить С++ записывать эту информацию. Мне придется определять и использовать кучу макросов. Я никак в С++ не могу сделать так, чтобы

class A
{
// ...
private:
    gc_ref<B> m_x;
};
Формировал для A какую-то метаинформацию. Понимаешь?

безусловно.

Тогда какой смысл называть это сборкой мусора?

И «само по себе» ничего не происходит.

Так при сборке мусора это делает сборщик мусора, отдельный модуль, являющийся частью среды. А у тебя что?

anonymous
()
Ответ на: комментарий от next_time

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

anonymous
()
Ответ на: комментарий от next_time

Вам с emulek, прежде чем утверждать, что в С++ можно сделать полноценный GC, неплохо бы было изучить, что собственно GC из себя представляет.

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

Формировал для A какую-то метаинформацию. Понимаешь?

нет. Честно. Зачем тут шаблоны?

Тогда какой смысл называть это сборкой мусора?

потому-что это сборка мусора. Те же алгоритмы, что у Кнута и в твоём любимом %ЯПname%

Так при сборке мусора это делает сборщик мусора, отдельный модуль, являющийся частью среды. А у тебя что?

а у меня отдельный модуль, который НЕ является частью C++. И это не баг, а фича.

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

Ну а подумать? Некоторое обозначение ссылки для объекта под управлением gc. Можешь поставить там A * или gc_ptr<A> или еще что-то на свой вкус.

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