Здравствуйте, AVC, Вы писали:
AVC>По сути дела, я осознал, что был не вполне прав, когда внушал Cyberax'у, что между bool и float нет ничего общего. AVC>Это общее есть, и это общее — (дурацкая, все-таки, прости Господи! не могу больше молчать! ) манера писать на Си выражения вида if (x) для произвольного типа. AVC>В нормальных языках пишут что-то вроде AVC>
AVC>if (x != 0.0)
AVC>
AVC>или AVC>
AVC>if (p != NULL)
AVC>
AVC>и т.п.
Абсолютно согласен! if(p) для небулевских типов (т.е. для которых приведение к bool не сделано осмысленно) — весьма дезинформирующая штука.
Здравствуйте, AVC, Вы писали:
AVC>Все зависит от реализованных алгоритмов. AVC>Если при нулевой экспоненте возможна ненулевая мантисса, то оператор нужен. AVC>Т.к. обычное сравнение
if (x)
уже не сработает правильно. AVC>В противном случае — "шаловливые ручки". AVC>Но это вряд ли. Раньше этого оператора там не было (я точно помню), и вряд ли он появился там "для красоты".
Погоди! При нулевой экспоненте очень даже возможна ненулевая мантисса, а как же иначе!
Вот при нулевой мантиссе ненулевая экспонента — это уже интереснее.
Здравствуйте, Кодт, Вы писали:
К>>4) Наконец, компилятор VC даёт предупреждение о приведении к bool и из bool в число. (Про другие компиляторы — врать не буду). Кому хочется развлечений — включайте опцию "treat warnings as errors" и наслаждайтесь.
К>Здесь я погнал. bool в число перевести — как нефиг делать. false==0, true==1. К>Здесь он от enum Bool {False,True} не отличается.
К>И, в ряде случаев, это фича.
Не везде. Так как true= !false то если расматиривать как безнаковые числа, абстрагируясь от битовых и логических операторов то для байта это будет 255.
WordBoоl дает честную -1, при приведении к инту
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Privalov, Вы писали:
P>Здравствуйте, Сергей Губанов, Вы писали:
СГ>>Весь смысл модульной системы как раз в том и состоит что модуль есть синглетон.
P>Все собирался спросить, а что будет, если пользователь захочет заменить загруженную в память версию модуля более свежей? Не ждать же, пока сборщик мусора выгрузит этот модуль.
У Вас путаница в голове. Сборщик мусора работает с памятью, а к модулям он никакого отношения не имеет. К модулям имеет отношение динамический загрузчик. Чтобы выгрузить загруженный ранее модуль нужно явно дать определенную команду. Например, в BlackBox модуль выгружается вызовом процедуры Kernel.UnloadMod(mod: Module); Впрочем, если этот модуль в данный момент используется другими модулями, то эта процедура ничего не делает.
К>Вот при нулевой мантиссе ненулевая экспонента — это уже интереснее.
Например, INFINITY.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Здравствуйте, Костя Ещенко, Вы писали:
КЕ>Здравствуйте, AVC, Вы писали:
AVC>>Видно, возмущение было столь сильным, что на критику уже слов не хватило? КЕ>Скорее удивление, сорри что не пояснил. Ты только что говорил о неявных приведениях в cpp как о зле (и я согласен), но приводишь пример, увеличивающий это самое зло.
Я уже покаялся за дезинформацию...
В действительности bool() делал проверку именно на нуль, как и положено в Си/Си++.
Это, конечно, не изменяет моей точки зрения, что неявное преобразование bool во float недопустимо по соображениям здравого смысла.
КЕ>Приведение float к bool возвращает false для 0.0 и true для остальных значений. А класс Float неявно приводится к float, и в то же время неявно приводится к bool, но по каким-то своим законам, отличным от float. Это никак не добавляет понятности в программу. Лучше ввести функцию is_valid() или типа того.
Совершенно согласен.
Тем более, что в Обероне только так и делают.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Здравствуйте, Serginio1, Вы писали:
К>>Здесь он от enum Bool {False,True} не отличается.
К>>И, в ряде случаев, это фича. S> Не везде. Так как true= !false то если расматиривать как безнаковые числа, абстрагируясь от битовых и логических операторов то для байта это будет 255. S> WordBoоl дает честную -1, при приведении к инту
Не надо смешивать. В Стандарте С++ прописано, что true=1. То же самое будет, если сделать через enum.
WordBool и прочая шняга пришла из VB/VBA, где "истина" — это байт или ворд, забитый единичками.
Между прочим, если x ненулевое, то ~x не обязательно нулевое Так что абстрагироваться от битовых/логических операторов нельзя.
Здравствуйте, Кодт, Вы писали:
К> Кстати, а это именно прямоугольник, или массив с рваным краем (jagged array) ?
В Обероне, в отличие от Java и от C#, массивы есть всякие.
Есть и те, которые (гипер)прямоугольные и те которые с разной длиной на каждую размерность. Соответственно есть массивы обычные (настоящие, статические) которые располагаются на стеке или прямо внутри объекта, а есть и ссылочные-динамические.
Например, можно объявить процедуру:
PROCEDURE Calculate (VAR mat: ARRAY OF ARRAY OF REAL);
VAR dim0, dim1, i, j: INTEGER;
BEGIN
dim0 := LEN(mat, 0);
dim1 := LEN(mat, 1);
FOR i := 0 TO dim0-1 DO
FOR j := 0 TO dim1-1 DO
mat[i, j] := 0.0;
END
END
END Calculate;
а потом скормить ей
PROCEDURE Test ( );
VAR
a: ARRAY 192, 256 OF REAL; (* Статический массив расположенный на стеке *)
b: POINTER TO ARRAY 4096, 1024 OF REAL; (* массив с заданными размерами находящийся в куче *)
c: POINTER TO ARRAY OF ARRAY OF REAL; (* прямойгольный массив с заранее не известными размерами *)BEGIN
Calculate(a);
NEW(b);
Calculate(b);
NEW(c, 8128, 512);
Calculate(c);
END Test;
Еще, естественно, можно работать с такими массивами mat: POINTER TO ARRAY OF POINTER TO ARRAY OF REAL — у него вторая размерность может быть разной в зависимости от "номера первой"... но такой массив в указанную выше Calculate уже передать нельзя (она принимает только прямоугольные). С таким массивом, естественно, надо будет работать так:
FOR i := 0 TO LEN(mat) DO
FOR j := 0 TO LEN(mat[i]) DO
mat[i, j] := 0.0;
END
END
Здравствуйте, Сергей Губанов, Вы писали:
AVC>> ...Там, правда, есть проблема с ковариантностью... СГ>В языке Component Pascal ковариантность есть!
Да, действительно есть.
Насколько я помню, результат процедуры-функции может быть ковариантным.
Но я еще не продумал следствия, вытекающие из этого.
Можно ли, используя это свойство, обеспечить статический контроль типов в контейнерах, что в Си++ делается с помощью шаблонов?
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
AVC wrote:
> КЕ>Приведение float к bool возвращает false для 0.0 и true для остальных значений. А класс Float неявно приводится к float, и в то же время неявно приводится к bool, но по каким-то своим законам, отличным от float. Это никак не добавляет понятности в программу. Лучше ввести функцию is_valid() или типа того. > > Совершенно согласен. > Тем более, что в Обероне только так и делают.
На всякий случай поясню свою точку зрения. Вне зависимости от того как работает operator bool(), лучше вообще его не вводить, в C++ "хватает" преобразования к float.
Здравствуйте, Кодт, Вы писали:
К>...Теперь достаточно в одной из функций подцепить указатель на сам объект и уйти в бесконечность.
Все гораздо проще.
Объекту вполне достаточно по своей воле не прекращать своей собственной активности хоть до бесконечности и он не будет никогда удален.
Рантайм система языка Active Oberon гарантирует, что сборщик мусора не будет удалять объект до тех пор пока он активный. После того как объект перестает быть активным, вот тогда сборщик мусора может его удалить если конечно на него нет ссылок. Ну это и понятно. Ведь когда объект активен, то по крайней мере одна ссылка-то на него всегда есть — ведь стоит же он в очереди за процессорным временем (своим time slice). Когда он перестает быть активным, то есть в очереди за процессорным временем он больше не стоит — по его душу придет GC и сделает свое дело.
Вывод — чтобы изничтожить неугодный активный объект достаточно убрать его из очереди за процессорным временем.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Serginio1, Вы писали:
К>>>Здесь он от enum Bool {False,True} не отличается.
К>>>И, в ряде случаев, это фича. S>> Не везде. Так как true= !false то если расматиривать как безнаковые числа, абстрагируясь от битовых и логических операторов то для байта это будет 255. S>> WordBoоl дает честную -1, при приведении к инту
К>Не надо смешивать. В Стандарте С++ прописано, что true=1. То же самое будет, если сделать через enum.
К>WordBool и прочая шняга пришла из VB/VBA, где "истина" — это байт или ворд, забитый единичками. К>Между прочим, если x ненулевое, то ~x не обязательно нулевое Так что абстрагироваться от битовых/логических операторов нельзя.
С точки зрения С++, а вот с точки зрения Delphi и OLE нормально. Мне лично больше нравится
true=~0 false=~~0 Хотя особенно и не настаиваю.
А вот сравнение действительных чисел на 0 как то не правильно учитывая относительность и погрешность.
Хотя все по ситуации.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Cyberax, Вы писали:
C>Сергей Губанов пишет:
>> Там где есть процессы/потоки — там нет активных объектов, и наоборот.
C>Ваш "активный объект" — это и есть поток.
Активный объект не поток, он концептуальный аналог максимально облегченного процесса.
Процессы/потоки — это абстракции операционной системы типа Windows/Linux и т.д., без операционной системы никаких процессов/потоков не существует.
Активные объекты — это некие первосущности существующие без операционных систем, операционные системы работают поверх них. Теоретически, можно выгрузить всю операционку, а кое какие объекты оставить в покое, потом загрузить другую операционку, а то и две сразу... Скажете фантастика?
СГ>У Вас путаница в голове. Сборщик мусора работает с памятью, а к модулям он никакого отношения не имеет. К модулям имеет отношение динамический загрузчик. Чтобы выгрузить загруженный ранее модуль нужно явно дать определенную команду. Например, в BlackBox модуль выгружается вызовом процедуры Kernel.UnloadMod(mod: Module); Впрочем, если этот модуль в данный момент используется другими модулями, то эта процедура ничего не делает.
Вот именно — ничего не делает. Я не о сборщике мусора спрашивал, а о том, как модуль обновить. Так что насчет путаницы в голове Вы, думаю, погорячились.
Сергей Губанов пишет:
> C>Сергей Губанов пишет: >>> Там где есть процессы/потоки — там нет активных объектов, и наоборот. > C>Ваш "активный объект" — это и есть поток. > Активный объект не поток, он *концептуальный аналог* максимально > облегченного процесса.
Поток характеризуется:
1. Параллельным выполнением.
2. Отсутствием неявного разделения данных.
И НИГДЕ здесь нет слов про Linux, Windows и ОС вообще...
"Активные объекты" удволетворяют обоим критериям.
Например, в MFC можно сделать "активный объекты", наследуя их от
CAppThread
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Все гораздо проще.
(не проще, а изоморфно)
СГ>Объекту вполне достаточно по своей воле не прекращать своей собственной активности хоть до бесконечности и он не будет никогда удален.
СГ>Рантайм система языка Active Oberon гарантирует, что сборщик мусора не будет удалять объект до тех пор пока он активный. После того как объект перестает быть активным, вот тогда сборщик мусора может его удалить если конечно на него нет ссылок. Ну это и понятно. Ведь когда объект активен, то по крайней мере одна ссылка-то на него всегда есть — ведь стоит же он в очереди за процессорным временем (своим time slice). Когда он перестает быть активным, то есть в очереди за процессорным временем он больше не стоит — по его душу придет GC и сделает свое дело.
Можно так сказать: все подлинно активные объекты зацеплены за очередь планировщика.
СГ>Вывод — чтобы изничтожить неугодный активный объект достаточно убрать его из очереди за процессорным временем.
Во-первых, вылететь из очереди планировщика можно тремя способами:
— из running в waiting
— из running в suspended
— из ready в suspended
Для вытесняющей многозадачности переход running->ready может случиться по внешним причинам (например, по прерыванию).
Это означает, что какой-то инвариант может быть нарушен. Естественно, после возврата в running инвариант объект восстановит инвариант; кроме того, программист всегда может установить, какие качества системы зависят от подвисания объекта, а какие не зависят и могут безопасно использоваться. Но сборка мусора — знает ли она об этом?
Во-вторых, вне зависимости от этого, сохраняется вопрос о легальности уничтожения ждущего объекта.
То ли этот объект зацеплен за очередь к ресурсу, то ли его оттуда можно смело выдёргивать.
В третьих, алгоритм работы объекта-демона принципиально состоит в бесконечном цикле (точнее, он выходит из цикла, получив сигнал остановки). А значит, он может что-нибудь зацепить...
Обнаружив факт полного выжирания памяти, сборщик мусора должен выяснить: какие демоны можно перезапустить. Как он это сделает, в условиях единого адресного пространства?
Здравствуйте, Костя Ещенко, Вы писали:
КЕ>На всякий случай поясню свою точку зрения. Вне зависимости от того как работает operator bool(), лучше вообще его не вводить, в C++ "хватает" преобразования к float.
В принципе, согласен.
Но, в данном частном случае, его введение, видимо, оправдано.
Пример я недавно приводил (в посте Кодту):
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Здравствуйте, Кодт, Вы писали:
СГ>>Вывод — чтобы изничтожить неугодный активный объект достаточно убрать его из очереди за процессорным временем. К>Во-первых, вылететь из очереди планировщика можно тремя способами: К>- из running в waiting К>- из running в suspended К>- из ready в suspended
ИМХО, это зависит от ОС.
Может быть три способа, а может быть тридцать три.
К>Для вытесняющей многозадачности переход running->ready может случиться по внешним причинам (например, по прерыванию). К>Это означает, что какой-то инвариант может быть нарушен. Естественно, после возврата в running инвариант объект восстановит инвариант; кроме того, программист всегда может установить, какие качества системы зависят от подвисания объекта, а какие не зависят и могут безопасно использоваться. Но сборка мусора — знает ли она об этом?
Для обеспечения сохранности инвариантов существуют мониторы. (Или другие средства синхронизации.)
Если система поддерживает мониторы, то неясно, почему могут быть нарушены (системные) инварианты.
К>Во-вторых, вне зависимости от этого, сохраняется вопрос о легальности уничтожения ждущего объекта.
Здесь нет ничего специфичного для ОС Оберон.
На что, кстати, уже обращалось внимание.
К>То ли этот объект зацеплен за очередь к ресурсу, то ли его оттуда можно смело выдёргивать.
Откуда?
Вопрос неясен.
К>В третьих, алгоритм работы объекта-демона принципиально состоит в бесконечном цикле (точнее, он выходит из цикла, получив сигнал остановки). А значит, он может что-нибудь зацепить...
Если активный объект цепляет что-то за свой стек (никак не привыкну к этому выражению ), то при его удалении память может быть освобождена.
К>Обнаружив факт полного выжирания памяти, сборщик мусора должен выяснить: какие демоны можно перезапустить. Как он это сделает, в условиях единого адресного пространства?
А как он это сделает в условиях нескольких адресных пространств?
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.