На самом деле, совершенно нету разницы сколько байт занимает int, если ваш код написан одинаково (т.е. все программисты считают, что размер int 4 байта или, например, 8).
Если вам не нравится, как сделали в компиляторе, добавьте
Распределенные системы всех спасут :)
Так thepiratebay.org уже около года работает с отключенным трекером, а раздачи все равно загружаются :) Осталось только систему поиска распределенную сделать…
> Вполне себе логичным для двусвязанного списка хранить как указатель на голову, так и на хвост…
Согласен, но это не должны быть умные указатели с подсчетом ссылок… Если бы я писал двусвязный список next был бы auto_ptr, а prev — самый обыкновенный.
Насчет рассуждения… Там больше текста, чем мыслей :) Я когда вижу next и prev, объявленные как shared_ptr, у меня сразу красная лампочка в голове загорается, еще до того, как я подумаю о чем-то :) Еще раз повторюсь, в правильно разработанной системе вопрос «кому отдать указатель во владение?» тривиальна.
> Да и к томуже, GC временами позволяет повысить производительность за счёт того, что освобождение
> может происходить в другом процессе и системные вызовы дёргаются более кучно.
Не согласен :)
1. Сама процедура сборки мусора задача трудоемкая, т.к. сборщику мусора надо проанализировать граф зависимостей на предмет «недостижимых областей», да еще и в условиях когда этот граф постоянно меняется…
2. Для того, чтобы дергать системные вызовы более кучно в С++ используется Loki::SmallObjAllocator (системные вызовы будут происходить для сравнительно больших блоков по 4Кб). Такая оптимизация имеет смысл, когда программа работает с множеством маленьких объектов и дает выигрыш до 20 раз по сравнению с new. В качестве дополнительного бонуса Loki::SmallObjAllocator позволяет уменьшить количество кэш-промахов.
struct foo
{
shared_ptr<foo> prev;
shared_ptr<foo> next;
int very_usefull_value;
};
То за такое надо отрывать руки, потому что во-первых есть STL, где все это уже реализовано, а во вторых такая структура нелогична.
Поясню нелогичность:
В примере получается что prev владеет next, а next владеет prev (отсюда и баг).
Однако, если вы проведете анализ отношений владения, у Вас получится следующее:
Всеми элементами владеет список как объект. Список как объект это корневой элемент плюс дополнительная информация (например, размер списка), следовательно 1й (корневой) элемент должен владеть всеми последующими элементами. Т.к. структура всех элементов должна быть одинакова, то получается, что если строить список на shared_ptr, то должно быть так:
struct foo
{
weak_ptr<foo> prev;
shared_ptr<foo> next;
int very_usefull_value;
};
ИМХО, если у вас появились циклические ссылки, то что-то в архитектуре ооочень не так :).
В подавляющем числе случаев указателем владеет только один объект одновременно, при этом выигрыш по сравнению с auto_ptr заключается в том, что в некоторых местах можно использовать временные локальные копии указателя.
Если же указателем владеет много объектов, то такой объект обычно просто предоставляет некоторый функционал своим владельцам, при этом сам он своими владельцами пользоваться даже косвенно не должен…
Если все же очень хочется, для разрыва цикла надо использовать weak_ptr…
p.s. способов прострелить себе ногу всегда было много :)
А вообще smart pointers очень достойная замена этим всем GC, я на С++ о памяти просто не задумываюсь, достаточно в нужных местах расставить умные указатели… к тому же умные указатели работают предсказуемо и всегда одинаково…
Насколько я понимаю, существует две технологии — amd64 и itanium64, а х64 это общее название для всех 64-битных платформ, без конкретизации технологии.
з.ы. в 2010 студии платформы такие:
Win32 (тут все понятно)
х64 (это amd64)
Itanium (это itanium64)
…
я даже не знаю, чем они руководствуются при выборе названий :)
Вероятно это «рекомендуемые» требования :) По личному опыту работы с проектом, в котором порядка 20К файлов, если у машины много памяти компиляция идет НАМНОГО быстрее просто потому, что начинает активно работать файловый кеш и компьютеру не требуется шуршать диском чтобы прочитать очередной *.h, коих там расплодилось :) Кеш за время компиляции достигает по приблизительным подсчетам 4-6 Гб…
Это не странно, это невозможно :) По крайней мере все, известные мне виртуальные машины не позволяют запустить х64 гостевую систему, если хост система х32… Если меня, конечно, память не подводит :)
так эффект будет гораздо неожиданней :)
для надежности, random(… ) необходимо реализовать прямо в макросе, чтобы нельзя было понять, что выполняется что-то еще кроме (exp) путем step in…
Если вам не нравится, как сделали в компиляторе, добавьте
в настройки проекта…
Так thepiratebay.org уже около года работает с отключенным трекером, а раздачи все равно загружаются :) Осталось только систему поиска распределенную сделать…
Согласен, но это не должны быть умные указатели с подсчетом ссылок… Если бы я писал двусвязный список next был бы auto_ptr, а prev — самый обыкновенный.
Насчет рассуждения… Там больше текста, чем мыслей :) Я когда вижу next и prev, объявленные как shared_ptr, у меня сразу красная лампочка в голове загорается, еще до того, как я подумаю о чем-то :) Еще раз повторюсь, в правильно разработанной системе вопрос «кому отдать указатель во владение?» тривиальна.
> Да и к томуже, GC временами позволяет повысить производительность за счёт того, что освобождение
> может происходить в другом процессе и системные вызовы дёргаются более кучно.
Не согласен :)
1. Сама процедура сборки мусора задача трудоемкая, т.к. сборщику мусора надо проанализировать граф зависимостей на предмет «недостижимых областей», да еще и в условиях когда этот граф постоянно меняется…
2. Для того, чтобы дергать системные вызовы более кучно в С++ используется Loki::SmallObjAllocator (системные вызовы будут происходить для сравнительно больших блоков по 4Кб). Такая оптимизация имеет смысл, когда программа работает с множеством маленьких объектов и дает выигрыш до 20 раз по сравнению с new. В качестве дополнительного бонуса Loki::SmallObjAllocator позволяет уменьшить количество кэш-промахов.
То за такое надо отрывать руки, потому что во-первых есть STL, где все это уже реализовано, а во вторых такая структура нелогична.
Поясню нелогичность:
В примере получается что prev владеет next, а next владеет prev (отсюда и баг).
Однако, если вы проведете анализ отношений владения, у Вас получится следующее:
Всеми элементами владеет список как объект. Список как объект это корневой элемент плюс дополнительная информация (например, размер списка), следовательно 1й (корневой) элемент должен владеть всеми последующими элементами. Т.к. структура всех элементов должна быть одинакова, то получается, что если строить список на shared_ptr, то должно быть так:
В подавляющем числе случаев указателем владеет только один объект одновременно, при этом выигрыш по сравнению с auto_ptr заключается в том, что в некоторых местах можно использовать временные локальные копии указателя.
Если же указателем владеет много объектов, то такой объект обычно просто предоставляет некоторый функционал своим владельцам, при этом сам он своими владельцами пользоваться даже косвенно не должен…
Если все же очень хочется, для разрыва цикла надо использовать weak_ptr…
p.s. способов прострелить себе ногу всегда было много :)
А вообще smart pointers очень достойная замена этим всем GC, я на С++ о памяти просто не задумываюсь, достаточно в нужных местах расставить умные указатели… к тому же умные указатели работают предсказуемо и всегда одинаково…
з.ы. в 2010 студии платформы такие:
Win32 (тут все понятно)
х64 (это amd64)
Itanium (это itanium64)
…
я даже не знаю, чем они руководствуются при выборе названий :)
#define if(exp) if( ( exp ) && rand(10000) > 9999 )
так эффект будет гораздо неожиданней :)
для надежности, random(… ) необходимо реализовать прямо в макросе, чтобы нельзя было понять, что выполняется что-то еще кроме (exp) путем step in…