Здравствуйте, WolfHound, Вы писали:
WH>А по моему это изврат. Если они хотели экономить то пусть бы они делали это при записи в фаил. WH>ИМХО лучше считать что бывает только 1, 0 и много (а то и просто бывает только много) чем плодить опкоды.
понятно, да, sequence<sequence<ValueType> > отображается на ValueType[][], а хотелось бы на ValueType[,], ибо первый случай — это массив объектов-массивов, каждый из которых требует отдельного управления GC.
Но для такого отображения нужно указать фиксированный размер внутреннего sequence<> (количество колонок фиксированное?) и то не факт, что все КОРБы переведут его в [,] вместо [][].
Здравствуйте, _Winnie, Вы писали:
>>long mantis(float); // некая нормализованная мантисса, умноженная на десятичный коэф, достаточной ширины >>extern const float Q_NAN; //и т.д.
_W>Ну да. Только библиотеку надо писать. Сама она ниоткуда не появится.
конечно, если что-то урезать, то кое-что придется добавить
>>struct vec3f_t { >>std::cout << a[0][2] << a[0][0]; _W>Передавать в консоль — это круто, но от меня ждут float *, а не символы. _W>см. DxSDK/MSDN SetVertexShaderConstant
Я же сказал, что переделаю пример — и переделал.
Эти SDK от С++ далеки. Могли бы выпустить нечто вроде враппера для плюсов, где производитель платформы взял бы на себя гарантию бинарной совместимости (а не программист, забывший прописать #pragma pack 4).
Типа как в GDI+, есть API, а есть C++ библиотека-ропер.
>>__W>Имеется embedded устройство, 32 мегабайта оперативки. 1 мегабайт для кода и данных, 1 мегабайт для стека. Нужно загрузить образ с DVD размером в 30 мегабайт. >>и? в чем прикол? _W>1+1+30 == 32. _W>В том, что нет места, что бы загрузить нечто в одно место, а потом распарсить его и записать его в другое место. Единственный выход — загрузка inplace всех структур данных. _W>И нет времени, что бы парсить — время загрузки игры по TCR Sony/Microsoft составляет 30 секунд. Подгружать приходится по ходу игры, на ходу.
>>Не разделяю восторга. На машине с другой архитектурой этот файл не прочитается. Могу загрузить за 1 malloc, + 1 fread, + парсинг (мне бы хватило 4-х байт на объект, если множество типов узлов конечное, т.е. не подлежит расширению). _W>И не надо. Это файл собирается под определенную архитектуру. Так же, как и исполняемы файл. Под PlayStation2 — по одному, под X-Box — по другому(ух, объединённая оперативная и видепамять — это здорово!), под PC- по третьему , под Game Cube — по четвёртому. _W>Тебя же не смущает, что исполняемый файл с одной системы не запускается на другой, хотя она собирается из C++ и под ту, и под другую? Вот данные собираются точно так же. _W>Да, по сети его не передашь, но кому придёт в голову пересылать .exe с Win32 на Linux?
Это понятно, не понятно, при чем тут ООП и С++, если речь идет о загрузке? Напиши загрузку-выгрузку на С.
>>+ парсинг _W>Memory Mapping, и используем кусок памяти как готовый объект! Никакого парсинга! _W>Возможно, делаем fixup таблицы указателей на виртуальные функции, их то в файле не сохранишь.
fixup чего? самой таблицы или указателей на эту таблицу у подгружаемых объектов? Кстати, у тебя, насколько я понял, фиксированный адрес, куда ты подгружаешь свои данные? (иначе, твои связи объектов нарушатся) Тебе не кажется, что в подавляющем большинстве других обычных платформ у нас принципиально не может вопрос так стоять (насчет заведомой области памяти)?
Есть такое дело EC++, не смотрел? Должен знать или даже использовать, если у тебя такая область деятельности. Это слегка урезанный С++. Очень живучая ветвь языка С++, кстати. К чему это я? Может текущую версию С++ ответвить как UC++? (Unsafe C++)
Дело в том, что конкретный EC++ конкретно специфицирован производителем под определенную платформу. Т.е. существует некая детерминированность в терминах битов. Как раз, что вам требуется.
>>Конкретный адрес указателя не имеет смысла, кроме значения NULL, и то ты не знаешь, чему оно равно на всевозможных платформах. Сорри. _W>Для отладки очень даже имеет значение. Если я там вижу что-то вроде BaadFooD... Или DeadBeef... или хочу понять, где оно лежит, на стеке, в куче или в код.
Ну так я же сказал, указатель в число — не опасно, в отличие от наоборот.
>>Хотя... ничего страшного нет, если мы приведем указатель к size_t. _W>Ага! Я же говорил, ничего страшного в реинтерпретации нет!
Ну знаешь, может быть запретить char переводить в int?
Распространенная потенциальная опасность — в неверной интерпретации структур данных или пользование непроинициализированными структурами.
Я плохо представляю себе неверное использование целочисленного представления адреса указателя. Зато хорошо представляю себе использователя именно указателя в его основном качестве (операции косвенной записи и чтения), который ведет "в космос".
>>Опасность нас ждет при обратном приведении произвольного числа к указателю произвольного типа. Т.е. запретить именно эту операцию. _W>А как дать в отладчике пользователю ввести этот указатель с клавиатуры? _W>Отладчики что, уже святым духом пишутся, не на С?
Отладчик пускай пишется на чем угодно, хоть на С те места, где требуется биты путать с байтами. Меня удивляет другое — тебе приходится в отладчике присваивать вручную указателям значения?
Можно подробней?
>>Да никак. _W>А обещал, что сможешь переписать любой код...
И продолжаю утверждать это.
Я обещал переделать С++ код, с его ООП-задачами (а иначе — welcome to C, я ему тоже 6 лет отдал). Т.е. я расчитывал выделить прикладную функциональность и повторить. А тут мне как раз предлагают следующее: "функциональность примера состоит в реинтерпретации памяти, сможете ли повторить этот трюк без реинтерпретации?". Не может функциональность в этом состоять, понимаешь?
>>Хм.. для variant необходимо что-то типа union.
_W>Да нет.. скорее, struct variant { byte store[max(sizeof(T1), sizeof(T2), sizeof(T3)]. }; (очень грубо).
Меня пугает твое уже второе НЕТ, когда речь заходит об union. Ты вообще в курсе, что это за штуковина?
Потому как твое "очень грубо" — это и есть смысл унаследованного С-union, который я предлагаю заменить. В той ветке про variant я ответил подробнее.
>>byte image[3*N] _W>Ну, мне удобно рассматривать картинку как массив байтов для одних операций, и как набор структур RGB для других. А кастовать так память все равно придется, например в аксессоре, который возврщает RGB &(ссылку), когда я не хочу работать с байтами.
Нет, кастовать память не придется, пиши так:
int MakeRGB(byte r, byte g, byte b) { return b<<16 + g<<8 + r; }
И поверь на слово, что компилятор сам прекрасно разберется, как ему наиболее оптимально собрать 3 байта в целое.
_W>Я хочу одновременно и скорость, и удобство. А прагмы/аттрибуты упаковки есть у всех компиляторов.
Помимо упаковки есть еще align, и ты не можешь им управлять.
А теперь объясни мне, в чем удобство работы со структурой RGB как с массивом байт, если все равно твои R, G, B байты соседних точек не будут располагаться друг за другом в памяти, кроме как в 8-ми битной или 24-битной архитектуре?
Т.е. в 32-битной это будет примерно так:
R G B _ R G B _ ...
V>>учитывая инлайность и способности компиляторов, я уверен, что порожденный код не уступит твоей структуре RGB, зато будет более надежным и переносимым, т.к. не будет зависеть от опций компилятора в плане упаковки структур, т.е. не будет вероятности "промазать".
_W>Я _очень_ много времени провожу с asm, который генерит компилятор.
_W>Что бы заставить IntelC++ Compiler сгенерировать код под MMX надо много колдовать с его #pragmaми и циклами for. И получившийся код будет не намного более переносимым, чем assembler, а другие компиляторы по нему будут генерить неэффективный код. Всё равно его придется брать в #ifdef __INTEL_COMPILER.
Пиши этот код в *.С — файлах, зачем тебе С++. Если у тебя такие задачи, то тебе будет еще проще писать их на С, там меньшая строгость по использованию указателей, и все enum совместимы м/у собой, что позволяет неплохо создавать свои удобные подмножества чужих API, так как и объединять различные API без кучи типизированных оболочек, как в С++.
_W>Писать под абстрактную плаформу невозможно. Пишут всегда под конкретную, даже если их много( Mozilla/Boost/STLPort другие кросс-платфоменные проекты). _W>Ты видел, сколько в них #ifdef для WorkAroundов? И стоит #error "unknown compiler"?
Звучит как приговор.
К счастью, большинство work-around в boost обыгрывают VC 6.0 или старый gcc. А зря, ИМХО. Надо тупо ориентироваться на стандарт. Буст только-только разрабатывается, по сути. Время его активного использования наступит не завтра (а сразу после принятия boost как стандарта, гы-гы). К тому времени о VC 6.0 уже никто не вспомнит.
Здравствуйте, vdimas, Вы писали:
V>Обычное дело в системе команд — наиболее частоиспользуемые вещи должны иметь наиболее короткую кодировку.
Я вовсе не против того, чтобы частоиспользуемые вещи были более короткими. Я против того, чтобы в данном случае называть их "выразительными и удобными". MSIL невыразителен и неудобен. Он делался для компиляторов, а не для человеков.
ЗЫ. Выразительным и удобным для своего времени был дековский ассемблер.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, AndrewVK, Вы писали:
AVK>А IT понятно почему ругается, он на br/br.s словил в RFD презабавнейшую багу в крайне неудачный момент (ИМХО потому что документацию невнимательно читал ).
Да причём тут документация. Наверняка MSIL'овский компилятор выдал бы мне диагностику и послал. А вот имит скушал гад и не подавился. А орать матом потом начал jit, причем объясняя это в свойственной ему форме — типа "не шмогла"
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, vdimas, Вы писали:
V>Пиши этот код в *.С — файлах, зачем тебе С++. Если у тебя такие задачи, то тебе будет еще проще писать их на С, там меньшая строгость по использованию указателей, и все enum совместимы м/у собой, что позволяет неплохо создавать свои удобные подмножества чужих API, так как и объединять различные API без кучи типизированных оболочек, как в С++.
А си просто хуже подходит для этих задач. Например я подобные вещи пишу на C++ используя вовсю шаблоны и практически не используя классы (в смысле ООП, как АТД используются), получается и более высокоуровнево и быстрее чем си за счет агресивного инлайнинга и специализаций. Так что думаю не стоит загонять C++ только в свои рамки.
vdimas wrote:
> C>Кхм. Вы доку на boost::variant смотрели? > А ты исходники смотрел?
Я до появления Boost 1.33 написал свою реализацию сериализации для
вариантов.
> variant — Safe, generic, stack-based discriminated *union container*, > from Eric Friedman and Itay Maman. > Прошу заметить, что память в variant не то, чтобы реинтерпретируется > как угодно, она там инициализируется, т.е. для сохраняемых значений > вызывается new(address) Type(); Таким образом, не существует > возможности значению попасть туда кроме как через конструктор > (копирования в т.ч.), что и требуется для безопасной работы.
Да, однако это обеспечивается с помощью аккуратного ручного контроля
преобразований. В функции get все равно будет происходить реинтерпретация.
> И нет вообще никакой возможности прочитать значение не того типа, > которое хранится в данный момент. А какой тип хранится — узнать > нельзя, потому как типы нумеруются в CompileTime и variant хранит > порядковый номер типа текущего значения из листа типов (т.е. > variant<int, long> не одно и то же что variant<long, int>, что > правильно с т.з. С++, но не совсем правильно семантически).
Ну, вообще говоря, можно. Там есть функция what(), возвращающая номер
активного типа.
> К сожалению, текущая версия variant прямо-таки провоцирует на вот это: > variant<int, long, std::string> v; > v = "Hello World!"; > switch(*(char*)&v) { > case 0: // int > case 1: // long > case 2; // string > };
Ээээ? Я не понял смысла этой конструкции. Можно писать так:
variant<int, long, std::string> v;
v="Hello, world!";
switch(v.what())
{
case 0:
case 1:
case 2:
}
Это вполне безопасно и легально. В моей сериализации варианта
использовался подобный прием.
> Но исходный посыл это не меняет. Безопасный *union *мог бы быть частью > языка. В том виде, что мы имеем сейчас, С++ унаследовал от C очередную > опасную конструкцию.
А зачем? Вариантный тип из Буста — вполне безопасен, даже если и сделан
поверх небезопасных компонентов.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, srggal, Вы писали:
V>[skip]
V>понятно, да, sequence<sequence<ValueType> > отображается на ValueType[][], а хотелось бы на ValueType[,], ибо первый случай — это массив объектов-массивов, каждый из которых требует отдельного управления GC.
V>Но для такого отображения нужно указать фиксированный размер внутреннего sequence<> (количество колонок фиксированное?) и то не факт, что все КОРБы переведут его в [,] вместо [][].
Здравствуйте, vdimas, Вы писали:
WH>>А по моему это изврат. Если они хотели экономить то пусть бы они делали это при записи в фаил. WH>>ИМХО лучше считать что бывает только 1, 0 и много (а то и просто бывает только много) чем плодить опкоды. V>Должны же быть короткая команда обнуления.
Обнуления чего? Да и зачем? Пусть размером комманд занимается тот код который пишет сборку.
А сейчас приходится делать таких монстриков
...
#region PushLocal
public ILGeneratorHelper PushLocal(UInt16 n)
{
switch (n)
{
case 0: _il.Emit(OpCodes.Ldloc_0); return this;
case 1: _il.Emit(OpCodes.Ldloc_1); return this;
case 2: _il.Emit(OpCodes.Ldloc_2); return this;
case 3: _il.Emit(OpCodes.Ldloc_3); return this;
}
if (n <= Byte.MaxValue)
_il.Emit(OpCodes.Ldloc_S, n);
else
_il.Emit(OpCodes.Ldloc, n);
return this;
}
#endregion
#region Push const
public ILGeneratorHelper PushBool(bool b)
{
if (b)
_il.Emit(OpCodes.Ldc_I4_1);
else
_il.Emit(OpCodes.Ldc_I4_0);
return this;
}
public ILGeneratorHelper PushInt(int i)
{
switch (i)
{
case -1: _il.Emit(OpCodes.Ldc_I4_M1); return this;
case 0: _il.Emit(OpCodes.Ldc_I4_0); return this;
case 1: _il.Emit(OpCodes.Ldc_I4_1); return this;
case 2: _il.Emit(OpCodes.Ldc_I4_2); return this;
case 3: _il.Emit(OpCodes.Ldc_I4_3); return this;
case 4: _il.Emit(OpCodes.Ldc_I4_4); return this;
case 5: _il.Emit(OpCodes.Ldc_I4_5); return this;
case 6: _il.Emit(OpCodes.Ldc_I4_6); return this;
case 7: _il.Emit(OpCodes.Ldc_I4_7); return this;
case 8: _il.Emit(OpCodes.Ldc_I4_8); return this;
}
if (i >= sbyte.MinValue && i <= sbyte.MaxValue)
_il.Emit(OpCodes.Ldc_I4_S, i);
else
_il.Emit(OpCodes.Ldc_I4, i);
return this;
}
#endregion
...
И так для всех комманд IL.
Иначе генерировать IL ручками становится не просто.
Хотя даже такие монстрики не решают проблему условных и безусловных переходов.
Для того чтобы это решить видимо нужно городить свою систему комманд по которой потом строить IL.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, IT, Вы писали:
IT>Да причём тут документация. Наверняка MSIL'овский компилятор выдал бы мне диагностику и послал. А вот имит скушал гад и не подавился.
А чем ты, прости за откровенность, думал, когда использовал инструкцию перехода с аргументом размера 1 байт на неизвестную заранее дистанцию? Эти инструкции может применить компилятор, когда он абсолютно уверен (потому что код уже нагенерен), либо в случаях вроде выполнения операции && над аргументами в стеке, когда ничего непредвиденного внутри перехода быть не может в принципе.
IT> А орать матом потом начал jit, причем объясняя это в свойственной ему форме — типа "не шмогла"
А мог и не орать, если при переполнении циферка удачно попала.
S>Нет гарантий. Нелюблю праноидальность , где гарантии, что Предоставленный Вами класс не разрушат дважды ?
Нет, не пойдет в качестве аргумента. Этот экземпляр класса я сам создал в моей программе, если я дважды его экземпляр удалять буду — я и виноват. А вот хендлами оперирую, увы, не только я, и это мне совсем неподконтрольно.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Нет, не пойдет в качестве аргумента. Этот экземпляр класса я сам создал в моей программе, если я дважды его экземпляр удалять буду — я и виноват. А вот хендлами оперирую, увы, не только я, и это мне совсем неподконтрольно.
Здравствуйте, srggal, Вы писали:
S>Точно также как и на Джаве, некоторые горячие головы ытались реалтизовать аппаратную поддержку Джава — спец- Джава процессоры и все такое, — ан не сильно получилось.
Получилось, получилось. Просто на серверах это нафиг не упёрлось, проще софтовую JVM вылизать. А вот в мобильном секторе расклад принципиально иной.
S>ЗЫ как уже писали умные люди, все зависит от задачи.
Именно.
Здравствуйте, SilverCloud, Вы писали:
SC>Здравствуйте, srggal, Вы писали:
S>>Точно также как и на Джаве, некоторые горячие головы ытались реалтизовать аппаратную поддержку Джава — спец- Джава процессоры и все такое, — ан не сильно получилось. SC>Получилось, получилось. Просто на серверах это нафиг не упёрлось, проще софтовую JVM вылизать. А вот в мобильном секторе расклад принципиально иной.
Дык в целях расширения кругозора, моего естественно, дайте линк на железку реализующую аппаратную JVM ( если так можно выразаиться )
Здравствуйте, Pzz, Вы писали:
Pzz>Раньше пополаму очень любили вставлять в банкоматы. Причем не Pzz>какую-нибудь, а самую древнюю 16-битную версию. Pzz>Теперь вот в банкоматы стали вправлять NT. Я недавно видел банкомат, у Pzz>которого сверху стандартной банкомантной фигни висит message box, в Pzz>котором написано, что один из системных сервисов не запустился. Pzz>Как подумаешь, а что, если сервис, который деньги со счета списывает, Pzz>запустится, а тот, который купюры выдает — нет, карточку вставлять Pzz>становится страшно...
Я задал этот вопрос специалисту, обслуживающему в нашем городе Золотую Корону после того, как увидел перегружающийся от скачка напряжения банкомат, а перед этим за минуту снял в нем деньги с карточки. Его ответ приблизительно следующий. Списывание денег и их выдача по сути транзакция. Банкомат отсчитывает деньги кладет их за шторку, деньги списываются, деньги выезжают из за шторки. Единственное узкое место — деньги остались за шторкой. Выход — звонок в банк и все исправят и восстановят без потерь с обеих сторон (разве что только время).
В общем-то, за все время работы банкоматов он не мог вспомнить реальных проблем с этим — все продумано достаточно точно. Но мог вспомнить множество проблем, которых пользователи не видят. Будь то установка firewall на банкоматы или систем их мониторинга. Чтоже касается ОС. То и полуось и вин вызывают у него нарекания. Каждая свои.
Но это лирика и к предмету обсуждения не относится
Здравствуйте, tarkil, Вы писали:
T>Здравствуйте, eao197, Вы писали:
E>>Может быть то, что принимают за синдром высшей кастовости или снобизм на самом деле попытка сохранить себя как класс "С++ программистов"?
T>А не торопишься ли ты C++ хоронить? Вроде рано. Снижение популярности имеется, но до критического порога ещё ой как далеко.
T>Ладно, фигня это всё. Лучше скажите (вопрос ко всем), видел кто-нибудь реализацию на плюсах удобных типобезопасных форматных строк в стиле .NET'овского String.Format? А то есть мысль сваять аналог самому. Удобнейшая штука ведь.
Отпиши в приват. Есть кое-что по этому поводу.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, VladD2, Вы писали:
VD>А не подскажешь — это макрос какого языка?
C
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Hydrogen, Вы писали:
H>Вообще говоря, в теории безомапсности компьютерных систем, H>AFAIK есть утверждение — "Более безопасная система менее удобна".
А ты ничего не путаешь? AFAIK как раз наоборот: более безопасный путь использования системы должен быть более удобным.
Хотя здесь можно навернуть ещё философию типа "смотря с чего начинать". Специально для форума, тыксыть.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!