1. Pascal / Говнокод #21962

    −18

    1. 1
    Знаете ли Вы, что в FreePascal блоки try..finally/except не работают в контексте DLL?

    Запостил: Dr_Stertor, 10 Января 2017

    Комментарии (129) RSS

    • Обрабатывать эксцепшоны внутри DLL - дурной тон (В Delphi исключение обычно перевозбуждают в хостовом приложении), поэтому в Лазаре блоки try...except послали нахуй.
      Ответить
    • > не работают
      Не ловят исключения или вообще не компилятся?
      Ответить
      • Не ловят.
        Ответить
        • А рантайм статический или динамический?

          З.Ы. Ну и исключение брошено из той же самой дллки, или из функции какой-то другой дллки или самого экзешника?
          Ответить
          • Статический, вестимо. В коде самой dll.
            Ответить
            • > В коде самой dll.
              Лол, т.е. dll'ка даже свои собственные исключения не видит в упор?

              З.Ы. Попробуй на динамический рантайм переключиться, если оно умеет (и в экзешнике и в дллке само собой).
              Ответить
              • В делфи есть галочка в настройках, а тут - хз даже как.
                Ответить
                • Хм, а я думал они эту настройку тоже передрали...
                  Ответить
                  • Должен признаться, что я хз что даёт динамический рантайм.
                    Приложение так или иначе всё равно грузит *.bpl-пакет в память, значит, дело не в выйгрыше в размере занимаемой памяти. А в чем тогда?
                    Ответить
                    • > не в выйгрыше в размере занимаемой памяти
                      В общем менеджере памяти и общей инфе о классах. Все дллки и экзешка с общим рантаймом как-бы сливаются в одно целое. Можно спокойно юзать ООП и прочие ништяки на всю катушку.
                      Ответить
                      • Т.е., это больше плюс, нежели минус?
                        Wow. Но это же замечательно. Можно запилить свое ООП с блэк-джэком и шлюхами.
                        Ответить
                        • > больше плюс, нежели минус
                          В общем-то да.
                          Ответить
                        • А статика больше подходит для одиноких dll'ок (всякие плагины) или exe'шек (простые проги из одной экзехи). Как-то так.
                          Ответить
                          • Кстати, недавно узнал, что VCL иногда создаёт глобальные утекающие объекты (объект висит в памяти до завершения работы приложения). Было неприятно. Ради интереса заменил borlndmm.dll на модифицированный, из пакета fastmm - оказалось, что среда разработки тоже сильно течёт.

                            Хз, ошибка это или нет. Система ведь всё равно подчистит. Но в своих прогах я очень щепетильно отношусь к утечкам.
                            Ответить
                            • > глобальные утекающие объекты
                              Ну это же не утечка, просто объект, закешированный в глобалку. Многие либы этим страдают.
                              Ответить
                              • лол, так любой static объект можно назвать утечкой, а еще страницы с кодом например
                                Ответить
                                • Ну тот же valgrind, емнип, их показывает, но отделяет от истинных утечек, называя "still reachable".

                                  З.Ы. "Любой static" всё-таки не лежит в куче.
                                  Ответить
                                  • ну ладно. А если у меня в статике ссылка на кучу и я ее free только в момент закрытия приложения? чем это плохо?

                                    Плохо когда они плодятся, когда через N часов работы у тебя куча такая что на тебя ООМКиллер поглядывает
                                    Ответить
                                    • @ну ладно. А если у меня в статике ссылка на кучу и я ее free только в момент закрытия приложения? чем это плохо?

                                      Здесь другой случай. Деструктор не вызывается вовсе и память освобождает сама система, в момент закрытия приложения.
                                      Ответить
                            • Самый прикол, что такие "утечки" есть даже в джаве и шарпе с их GC.
                              Ответить
                              • Какой лютый пиздец... Я просто вне себя.
                                Т.е. обеспечивается "резиновый" размер памяти, но это даётся ценой размещения в ней висячих объектов?
                                Ответить
                                • Ты о чем, наркоман?
                                  Ответить
                                  • Я не наркоман.
                                    Речь о том, что сборщик мусора должен быть активен вплоть до завершения работы проги, а сам при этом утечет.
                                    Ответить
                                    • Не осилил понять эту фразу.

                                      Не поможешь?
                                      Ответить
                                      • @Не осилил понять эту фразу.

                                        Я так понимаю, что идёт обмен шила на мыло.
                                        Что представляет собой GC? Наверняка, это какой-то глобальный объект для подчищаемой проги, который управляет ее памятью. Если его инстанс создаётся каждый раз для каждой проги, по завершению ее работы он "утекает" - т.е., он же не может деаллоцировать сам себя - его прихлопывает система.
                                        Ответить
                                        • > не может деаллоцировать сам себя
                                          Да и хуй с ним, он ничтожно мал по сравнению с тем, что он успевает почистить за свою жизнь.

                                          З.Ы. Утечки мало кого беспокоят после смерти. Главное - чтобы они не мешали при жизни :)
                                          Ответить
                                        • Не объект, а скорее поток и много всякого стаффа в памяти;))

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

                                          Что плохого?
                                          Ответить
                                          • @скорее поток и много всякого стаффа в памяти;)

                                            Дополнительный поток, который чистит память своего же процесса?
                                            Ответить
                                            • Да.

                                              Ну точнее это конечно зависит от реализации. Думаю что ты имеешь право реализовать так, как тебе удобно, но вот JVM это так, думаю то и в .NET так же.
                                              Ответить
                              • Конечно, если на них есть ссыль из пермгена.
                                Где, по твоему, лежит синглтон со своими полями?
                                Ответить
                            • > объект висит в памяти до завершения работы приложения
                              Это норма, и такое вообще часто используется. Для быстродействия в том числе: если программа работает недолго и вызывается часто (что-то типа grep или cat) то нефиг ей перед завершением в куче рыться, деаллоцируя заведомо обречённые на гибель объекты.
                              Ответить
                              • Так может и файлы, открытие на чтение можно не закрывать?
                                Ответить
                                • Файлы лучше закрывать как можно раньше, чтобы писателей не обламывать.
                                  Ответить
                                  • Память лучше освбождать как можно раньше, чтобы аллокаторов не обламывать.
                                    Ответить
                                    • > Память лучше освбождать как можно раньше
                                      Т.е. GC - говно, т.к. освобождает её в самый-самый последний момент, когда аллокатор вот-вот обломится?
                                      Ответить
                                      • Конечно, референс каунтинг наше всё:)

                                        ладно, я понял разницу: файл может быть нужен конкретный, а память не важно какая: главное, чтобы была
                                        Ответить
                                        • > референс каунтинг
                                          Тормозной, неполноценный, ненадёжный, ненужный.

                                          То ли дело машина Тьюринга с бесконечной лентой.
                                          Ответить
                                          • > с бесконечной лентой
                                            Лента - медленная хуйня с последовательным доступом. То ли дело бесконечная память...

                                            З.Ы. Но как эту бесконечную память адресовать?
                                            Ответить
                                            • >>З.Ы. Но как эту бесконечную память адресовать?
                                              С помощью регистра бесконечного размера конечно же
                                              Ответить
                                            • Нужен MMU с поддержкой фрактальных страниц памяти.
                                              Ответить
                                          • Не знаю, ARC в ObjC был достаточно годен.
                                            Разница в использовании по сравнению с GC только в невозможности выпилить isle of isolation, и потому нужно было понимать в какую сторону можно делать strong ref, а в какую -- нет, что порождало говнопаттерны типа "strong weak dance", зато никто не широёбился в фоне и не искал пути к объекту из стеков потока и пермгена. Может быть потому айфон дольше держит зарядку, чем андроидные девайсы?;)

                                            Но если совсем по честному, то я от ручного управления памятью не умирал: надо было быть очень внимательным
                                            Ответить
                                            • > Не знаю, ARC в ObjC был достаточно годен.
                                              Не знаю, как в ObjC, но в йеху он меня не впечатлил.
                                              http://govnokod.ru/19104
                                              Ответить
                                              • Я не умею в свифт, но если я верно понял то это тот самый островок, о котором я говорил вышел.

                                                Если у тебя A ссылается на B, а B на A то одна из ссылок должна быть weak (тоесть на каунтинг не влиять и обнуляца).

                                                В твоем примере тоже самое только A и B у тебя инстансы одного класс.

                                                Кстати, в UIKit есть очень четкие конвенции на этот счет: контроллер имеет ссылки на свои элементы, а они на него weak, и потому когда на контроллер никто не ссылается то его можно уебать, и его потомки дадут дуба вместе с ним. А буть ссылки жесткие -- ты бы их никогда бы не удалил
                                                Ответить
                                                • Не, дело не в этом. Там рантайм падает в stack overflow при попытке рекуррентно(!) освободить память.
                                                  Ответить
                                                  • так)

                                                    Вот тут p ссылается на p0: var p = R(a : p0)
                                                    А вот тут p0 на p: p0._a = p

                                                    Обе ссылки стронговые. Objc мог смело сделать memory leak, а сырой стриж запутался и наступил себе на шнурки.

                                                    В любом случае ты НЕ прав: ты сделал некрасиво.
                                                    Ответить
                                                    • > p0._a = p
                                                      > if leak
                                                      > test(noLeak, leak: false)
                                                      Ответить
                                                      • ну вот когда ты сказал leak: true то получил leak, а при _достаточно_большом_ размере твоей структуры ты вместо обычного лика получил SO.

                                                        Я тебя верно понял? У меня нет ябла просто чтобы собрать, а из твоих комментов я сделал именно такой вывод.
                                                        Ответить
                                                        • Да, верно, за исключением того, что размер структуры был весьма скромным. Для сравнения, в любом языке с GC подобные списки можно делать на порядки длиннее.
                                                          Ответить
                                                          • А почему ты думаешь что ДОСТАТОЧНО_БОЛЬШОЙ > ВЕСЬМА_СКРОМНЫЙ ?

                                                            В общем я согласен с тем, что свифт повел себя как говно. Но это вопрос не к RC а его реализации.

                                                            Было бы здорово, если бы reference cycle был бы объявлен UB
                                                            Ответить
                                                          • А с виком пробовал?
                                                            Ответить
                                                            • > с виком
                                                              Развалится же сразу.
                                                              Ответить
                                                              • чойто?
                                                                Все кошерненько соберется и уйдет в помойку.

                                                                В Objc посылка сообщения нилу валидна, думаю что и в свифте тоже.
                                                                Ответить
                                                                • > Все кошерненько соберется и уйдет в помойку.
                                                                  Будет точно то же самое, что и в случае с leak:false.
                                                                  Ответить
                                                                • > Все кошерненько соберется и уйдет в помойку.
                                                                  Угу, даже не успев построиться (что я и имел в виду под развалится). Как я тебе вилкой на виках буду список строить?

                                                                  З.Ы. Или ты только про последний замыкающий элемент?
                                                                  Ответить
                                                  • > рекуррентно(!) освободить память
                                                    Ну тут, в общем случае, задача хреновая. Можно разве что заменить рекурсию очередью. А чтобы не выделять память при освобождении памяти - строить эту очередь из тушек освобождаемых объектов, у которых деструктор уже позвали.
                                                    Ответить
                                            • > зато никто не широёбился в фоне и не искал пути к объекту из стеков потока и пермгена

                                              Вот без гц могут возникать детерменированные, но такие охуительные паузы в программе, что любой го позавидует. Я как-то в одной программе сделал очередь для ненужных объектов и фоновый поток неспешно подчищающий эту очередь, потому что в определнных условиях программа могла надолго подвисать, 90% времени занимаясь удалением кучи таких объектов. Кажется это решение заслуживает собственного треда на говнокоде.
                                              Ответить
                                              • Звучит маловероятно. Программисты на с++ не создают столько мусора (с).

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

                                                Насколько мне известно, в гейдеве довольно распространенный подход, когда очередной уровень инициализируется.
                                                Ответить
                                                • Там проблема была в том, что деструктор делал некоторую тяжелую работу. И 100500 объектов становились мусором, когда 100500 клиентов одновременно отключались от сервера.
                                                  Ответить
                                                  • > делал тяжелую работу
                                                    Ну т.е. виновато совсем не управление памятью. С гц было бы то же самое (т.к. тяжелую работу один хер надо выполнить).
                                                    Ответить
                                                    • > С гц было бы то же самое
                                                      > тяжелую работу один хер надо выполнить

                                                      GC может такие вещи амортизировать, выполняя не всю работу сразу и уменьшая contention. Но поскольку делать в финализаторах "тяжёлую работу" — плохая идея, нужно всё равно пилить очередь (в жабе, к примеру, есть reference queue), которая будет потихоньку подчищать в одном потоке. Правда, в качестве платы за меньшие паузы, high water mark использования удяляемых в бэкграунде ресурсов может заметно подрасти.
                                                      Ответить
                                                  • - Почему кот яйца лижет?
                                                    - Потому что может.

                                                    Если у тебя там какая-то тяжелая работа - а как по мне тяжелая работа это пописать в базу или пообщаться с другими модулями/сервисами - то это совершенно точно не надо делать в деструкторе. Даже если там объект должен уведомить о своей кончине кучу мониторящих каких-то менеджеров - это не должно быть в деструкторе.

                                                    Если бы у тебя там на shared/weak ссылках был организован лайфтайм объекта, то вышенаписанное было бы самоочевидно - у тебя бы не получилось засунуть в деструктор тяжелой работы, т.к. это этап, когда уже поздно пить боржоми.
                                                    Ответить
                                                    • > это не должно быть в деструкторе

                                                      Схуяль? И тяжелая работа - это то, что заставляет 500к деструкторов отрабатывать заметное время.

                                                      > Если бы у тебя там на shared/weak ссылках был организован лайфтайм объекта, то вышенаписанное было бы самоочевидно - у тебя бы не получилось засунуть в деструктор тяжелой работы, т.к. это этап, когда уже поздно пить боржоми

                                                      Схуяли?
                                                      Ответить
                                                      • > Схуяль
                                                        У деструктора нет никаких других результатов кроме корректной очистки, у него нет шансов наткнуться на неработающий или блокирующий внешний ресурс, т.к. ему некогда ждать и тем более делать второй заход. В деструкторе должно быть только то, что зависит от самого объекта и рантайма.

                                                        > shared/weak
                                                        Отличный пример, что деструктор не вызывается тобой, а только тогда, когда объект не нужен никому, не должен никому, и поэтому он спокойно умирает, не дергая больше ничего - он уже дёрнул все что нужно пока был живой (и оставался нужным кому-то).
                                                        Ответить
                                                        • > У деструктора нет никаких других результатов кроме корректной очистки

                                                          Погугли RAII.

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

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

                                                            И пример, когда ты не можешь предположить более очевидное место, где эта бизнес-логика должна произойти - ведь счетчик ссылок не уменьшается просто так

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

                                                            Подумай на досуге, как реализованы те же задачи на языках, где деструкторов вообще нет, а на финалайз никакой надежды. Про кота - это именно об этом. Потому что может.
                                                            Ответить
                                                            • Ты видимо никогда не использовал asio и не знаешь, что у объекта выполняющего несколько асинхронных операций одновременно сложно отследить лайфтайм. А еще ты похоже думаешь, что я использую шаредпойнтеры, потому что мне скучно. Если бы в коде было одно место, где объект может доделать все дела, я бы воткнул в это место delete и не использовал шаред пойнтер.
                                                              Ответить
                                                              • > я бы воткнул в это место delete и не использовал шаред пойнтер использовал value / unique_ptr.

                                                                fixed
                                                                Ответить
                                                                • Если речь про асинхронного питуха, то там же нет скоупа, в конце которого юник пойнтер может умереть - какую-то операцию удаления придется позвать руками.
                                                                  А если речь про потоки/корутины, то лучше прямо на стеке.
                                                                  Ответить
                                                                  • А, там и написано value. Да, все так, долблюсь в глаза.
                                                                    Ответить
                                                              • Лол я асио использовал с буста 1.37. Патчил его таймеры, когда еще хроно не было даже в бусте, а имплементация из коробки страдала от перевода системного времени. Использовал асио для пердоликса, шиндошс, для тисипи, юдипи и даже дохуя ком.

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

                                                                Ладно, /thread.
                                                                Ответить
                                                    • > у тебя бы не получилось засунуть в деструктор тяжелой работы

                                                      Ну вот недавний пример из жизни (код был не мой, разумеется): попробуй реализовать бинарное небалансируемое дерево, которое хранит потомков в shared_ptr, а потом сделай ему 500 уровней, запасись попкорном и смотри, как переполняется стек при уничтожении корня.

                                                      > С гц было бы то же самое

                                                      Не совсем, см. пример выше. Различие в том, что GC обходит дерево объектов в ширину, а деструкторы — в глубину. Поэтому в языках с GC проще и более безболезненно создавать глубоко вложенные структуры данных.
                                                      Ответить
                                                      • Это не тяжелая работа. Признаки тяжелой работы я выше написал.

                                                        А тут всего то воркэраунд над тем, что не подошли размеры стека, подходящие в 99.999% остальных случаях (кстати, лень проверить, но 500 не выглядит каким-то конским числом, просто поверю).

                                                        Переписав деструктор с дефолтного ты получишь те же миллисекунды выполнения и независимость от долгих внешних ресурсов.
                                                        Ответить
                                                        • > 500 не выглядит каким-то конским числом

                                                          У нас обычно работает куча тредов, которые делают простые задачи. Поэтому дефолтные размеры стека на уровне килобайтов.
                                                          Ответить
                                                        • Кстати, довольно простой деструктор то выйдет, с малым оверхедом.
                                                          Ответить
                                                          • > Кстати, довольно простой деструктор то выйдет, с малым оверхедом.
                                                            ~tree_node() {
                                                              if (left) work_queue.push(&release_node, left);
                                                              if (right) work_queue.push(&release_node, right);
                                                            }
                                                            ?
                                                            Ответить
                                                            • Нет. Создаем вектор. Подбираем параметр достаточной глубины, чтобы ничей брат не умер. Например, 100. Обходим дерево, как только достигаем глубины, кратной этим 100 - помещаем себя в вектор, зануляем у родителя ссылку на текущую ноду.
                                                              Все, обхода достаточно - дальше деструкторы корня (в нем уже только 100 глубина лежит) и вектора отработают сами без переполнения стека.
                                                              Ответить
                                                              • > как только достигаем глубины, кратной этим 100
                                                                Откуда ты в деструкторе узнаешь, какая у тебя глубина? Проще уж выкинуть деструкторы нодов совсем и сделать так:
                                                                struct tree_node {
                                                                  // ...
                                                                  tree_node* left;
                                                                  tree_node* right;
                                                                
                                                                  struct deleter {
                                                                    void operator()(tree_node* root) const {
                                                                      std::vector<tree_node*> queue;
                                                                      bfs_tree(root, queue);
                                                                      for (auto ptr : queue) delete ptr;
                                                                    }
                                                                  };
                                                                };
                                                                
                                                                using tree_ptr = std::unique_ptr<tree_node, tree_node::deleter>;
                                                                Ответить
                                                                • В деструкторе дерева, а не ноды дерева. Проблема то именно в дереве, а не ноде.
                                                                  Ответить
                                • Ответить
                                  • > FlushFileBuffers
                                    > не будет скинут на диск
                                    >> на чтение
                                    Ответить
                                    • А-а-а... В этом случае однозначно надо закрывать, особенно, если режим не FILE_SHARE_READ or FILE_SHARE_WRITE.
                                      Ответить
                                      • Vanished
                                        Ответить
                                        • > почему мы считаем что файл может кому-то понадобиться, а память нет
                                          Потому что память - однородный ресурс. Эти 100 мегабайт или другие 100 мегабайт я держу - всем похуй. А файлы нужны конкретные.
                                          Ответить
                                          • да-да, я уже и сам понял: http://govnokod.ru/21962#comment365818
                                            Ответить
                                        • CompareMem('xuj','palec')= ?
                                          Ответить
                                          • > CompareMem('xuj','palec')= ?
                                            Длину не указал, на которую сравнивать.
                                            Ответить
            • З.Ы. А кстати, а 32 или 64 бита? И версия FPC какая.
              Ответить
              • 32 бита. Да на всех вроде версиях... lazarus.freepascal.org
                Лазарь-это визуальная среда, где компилер - fpc. Там всегда новые версии, а я скачивал недавно, месяц назад.
                Ответить
                • Понятно. Просто в гугле попадался баг, что 2.6.х на 64-битке был какой-то баг с исключениями и dll. Значит не оно.
                  Ответить
    • А кого ибёт щас паскаль, вообще?
      Ответить
      • В кои-то времена в треде возникла тёпло-ламповая обстановка, как много лет назад.
        ,и вот, обязателно должен был прийти какой-то гомосексуалист и всё испортить...
        Если честно, я ждал, что придёт Инканус - но, почему-то не пришёл.
        Ответить
        • > я ждал, что придёт Инканус

          А что если я и есть...
          Ответить
          • Не думаю. Лица, в чьём распоряжении есть официальные учётки, не сидят под всякими там guestinho
            Ответить
            • или huestinho
              Ответить
            • У меня официальных учетох хоть жопой жуй (я один из августовских ботоводов). Ты просто дурачек и не понимаешь романтику анонимности.
              Ответить
              • +1
                Ответить
              • В слове "дурачок", как Вы можете видеть, буква "ё" отсутствует... Ну да Бог с Вами.
                Романтика может и есть, спорить не буду, но взамен Вам гарантировано прохладное отношение товарищей, привыкших к тому, что новички зачастую выкидывают нелицеприятные номера.
                Ответить
                • 1024--, перелогинься
                  Ответить
                  • Зачем мне перелогиниваться? Вы же и так знаете, кто есть кто.
                    Ответить
                  • Я некогда писал, что не осилил правило "о/е/ё после шипящих". Соответственно не замечаю подобные огрехи у своих оппонентов. Паскаль забыл, Дельфи не знаю. Зачем мне логиниться?
                    Ответить
                • >>и есть - спорить не буду
                  Зачем тут дефис?
                  Ответить
                  • 1024--, перелогинься
                    Ответить
                    • Я люто, бешено равнодушен к жабьему скрипту, а стало быть не могу быть 1024.
                      Ответить
                      • Это был сарказмус.
                        Ответить
                        • Я не верю что программист на FreePascal может в сарказмус
                          Ответить
                          • Палочка, а можешь ли ты объяснить нам на пальцах, в чём разница между тирэ и дефисом?
                            Ответить
                            • Конечно.
                              Тире длиннее минуса.

                              хуй большой а ландыш маленькиииий
                              Ответить
                              • Ответ неправильный. Тире разделяет слова, а дефис - связывает. Иными словами, дефис - орфографический знак.
                                примеры использования дефиса:
                                человек-оркестр, ковёр-самолёт, где-то, что-то, откуда-то....
                                Ответить
                                • --чем яблоко отличается от банана?
                                  --банан длинный, а яблоко нет
                                  --Ответ неправильный. Спелый банан не бывает зеленым, а спелое яблоко бывает.

                                  >>Тире - разделяет слова, а дефис - связывает.
                                  Опять путаешь. Ох.
                                  Ответить
                                  • @>>Тире - разделяет слова, а дефис - связывает.
                                    Опять путаешь. Ох.

                                    Держи пруф с википедии:

                                    Не следует путать дефис и тире. Дефис — орфографический знак, тире — пунктуационный. Кроме того, тире в русской типографике (но не в англоязычной), в отличие от дефиса, отбивается пробелами
                                    Ответить
                                    • Неправильный вариант от стертора:
                                      >> Тире разделяет слова, а дефис - связывает.

                                      Правильный от вики
                                      >> Дефис орфографический знак
                                      Ответить
                  • Это тире
                    Ответить
                • Ты мне не товарищ.
                  Ответить
        • >>В кои
          Вот именно что в KOI, а уже 15 лет как KOI8-R не нужен
          Ответить
      • никого
        Ответить
      • Классический Паскаль уже давно не нужен. Но здесь речь об Object Pascal. Путать их — всё равно, что писать: требуется специалист по C/C++/C#/Objective-C/D.
        Ответить
        • А Object Pascal нужен?

          Кстати, я в детстве писал писал на Trubo Pascal 7.0 и говорил что пишут на паскале. А ведь это была неправда: в классическом паскале не было объектов.
          Ответить
          • Если Embarcadero выпускает новые версии Delphi XE, если не загнулись Фрипаскаль, PascalABC.NET, Oxygene, значит, кому-то нужен.

            Надо же на чём-то писать Total Commander!
            Ответить
            • Послушайте, ну если звезды зажигают то это вовсе не значит что оно кому-то нужно:

              * https://wiki.mozilla.org/Ports/os2
              * http://www.parser.ru/

              >> PascalABC.NET,
              Слышал, что в Питере на нём детей учат, потому что курсы по паскалю с 1996 года не сильно поменялись.
              Ответить
              • Delphi XE и Oxygene — коммерческие проекты. Ну не могут коммерческие проекты существовать долго, если они никому не нужны.
                Ответить
                • Но может быть там такая же ситуация как с IBMовскими мейнфреймами?

                  На них просто такая уже кодовая база что выкинуть, переписать и переучить будет стоить охулион долларов?
                  Ответить
                  • Эта категория покрывается делфи 7. Зачем им эмбаркадеро какой-то?
                    Ответить
              • @PascalABC.NET
                Хромой аналог Delphi 8, на костылях.
                Ответить
                • Зато лёгкий доступ к .NET, а значит всё новомодное
                  Ответить
      • Никого, уже 354 года.
        Ответить
    • А вот и первая шеренга минусов.
      Они горят, словно капельки жизни на фартуке студента-хирурга.
      Ответить

    Добавить комментарий