Home

Advertisement

Customize

Глубоко в Джунглях

Jul. 30th, 2009

02:34 am - Классический взлом

197x-год, машина PDP-10, операционная система TENEX -- одна из первых ОС с виртуальной памятью. Проверка пароля производится примерно таким кодом:

    int len = strlen(directoryPassword);

    for (i = 0; i <= len; i++)
    {
        if (directoryPassword[i] != passwordArgument[i]) 
        {
            return 1; // плохой пароль
        }
    }

    return 0; // хороший пароль

Где directoryPassword это известный системе пароль (пароль на каталог, насколько я понял), а passwordArgument передаётся пользователем.

Конечно это псевдокод, а не кусок настоящего исходника. И даже псевдоязык: реальная TENEX была написана на ассемблере, даже UNIX была переписана на C только в 1973-м. TENEX появилась раньше, эта уязвимость в OSDVB помечена 1972-м годом.

Что делают плохие парни?

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

Ну, и? )

Конечно, им капитально не повезло. Достаточно было написать strlen(passwordArgument) и дырки бы не было. Или скопировать пароль в буфер. Но зато какой пример! Если бы его не существовало, его следовало бы выдумать :)

Это невероятно красиво. Это атака, не больше не меньше, на модель реальности. Конкретно -- на представление об адресном пространстве как о массиве байт. С абстрактной программистской точки зрения это представление верно, но есть нюансы... Как в задаче про лампочки.



Запись в osvdb: http://osvdb.org/23199
Описание: http://www.scs.stanford.edu/nyu/02sp/notes/l2.pdf (первые две страницы; там ещё дальше что-то, но я не вдавался)
Подробное описание: http://www.st.cs.uni-saarland.de/edu/secdesign/coding.pdf (страницы 4-14, дальше глянул, но оно не очень интересно и местами даже не очень правильно)

А я прочитал об этом баге в книжке 19 смертных грехов. Она неплохая, но удивительно скучная. Вроде такая тема благодатная, но дочитывал с баальшим трудом.

May. 19th, 2009

03:33 pm

Продолжая тему предыдущего поста :) Вообще, исходно он был совсем не про образование, а немного шире, именно про пользу от теории... Но потом куда-то свернули. Ну да ладно, свернули так свернули.

Вывод будет в конце.



... именно из-за этого, как мне кажется, в программировании столько "дилетантов" :) Чтобы стать физиком нужно много учиться, чтобы стать строителем нужно много учиться, чтобы стать химиком нужно много учиться... Чтобы стать программистом? Уважаемые [info]lumag и [info]ran_dom оба физики, оба с Политеховского Физтеха [и ещё одна особенность обучения у них общая, кстати; ребята, знакомьтесь :)]. На кого учился [info]ushastyi я не знаю. [info]lazy_frog лингвист и психолог. Я, ребята, единственный из вас учился на что-то типа программиста :)

По идее меня пять лет натаскивали и обучали программировать. За пять лет можно горы свернуть. По идее я должен быть мегакрут. Видимо что-то не так со мной... Однако, из моей группы кроме меня в программисты пошло человека два. Большинство -- в тестеры. Староста -- в стройальпы. Хотя ведь они все прошли этот бесчеловечный пятилетний тренинг.

Ну да, допустим Политех suxx, особенно наша кафедра, и это действительно недалеко от истины. Но как же эти физики, химики (есть соответствующий знакомый) и лингвисты (вот позор на нашу "техническую" специальность!) программируют?!

А очень просто. Дело в том, что вас обманывают. Дело в том, что "прикладное" программирование это не просто, а очень просто. Сферический прикладной программист не должен знать и уметь:

  • Железо, ассемблер, регистры, двоичная система счисления -- все такие вещи абсолютно не нужны. Мы используем языки высокого уровня, а часто и вообще скрипты.

  • Алгоритмы, математику вообще. В любом языке есть функция sort, есть hashmap, есть ассоциативный массив какой-нибудь. Что там ещё надо-то?

  • SQL и реляционную алгебру. Современные ORM прекрасно справляются.

  • Как устроены сети ниже уровня "поток байт". Концепция сокета прекрасно маскирует всё нижележащее начиная с 80-х. А по последним данным сетей вообще нет, удалённые вызовы ходят прозрачно.

  • Концепция файла эффективно скрывает все детали реализации файловых систем, все эти сектора и кеши.

  • Выделение памяти происходит тоже само.

  • Без многопоточности можно прекрасно обойтись в 99% случаев. Более того, это таки действительно хороший стиль -- без неё обходиться.

  • Детали реализации ОС тоже не нужны.

  • Пролог, хаскель, схема и прочая такая же ботва

Что там осталось?

  • Синтаксис языка программирования

  • Любимая библиотека

Всё! Это, вообще-то, с трудом тянет на двухгодичное обучение в ПТУ.

Да, действительно, есть особые отряды программистов специального назначения... Некоторые из них, например, знают SQL. Таких днём с огнём ищет [info]plugimz (точнее, раньше искал). Или кто-то знает низкий уровень, такие нужны [info]ran_dom. Для разработки игр требуется примерно один человек, который сечёт в алгоритмах и оптимизации. Хорошо бы он принимал участие в написании движка. Для собственно конкретной игры он не нужен. Когда пишут ОС кто-то должен знать про процессор, кто-то другой про файловые системы, ещё кто-то -- про сети, про алгоритмы распределения памяти. Ну и т.п.

Конечно, при прочих равных, приятно, когда у тебя умные коллеги, с которыми можно пообсуждать что-нибудь в перерыве. Как выясняется, в среднем физики и математики и лингвисты более чем удовлетворяют этому требованию. Конечно, редко-редко бывают ситуации, когда мифологические представления (о железе, об ОС), складывающиеся у сферического прикладного программиста оказываются неадекватны, причём настолько, что это влияет на код, причём так, что код не работает. В этом случае он попадает в затруднение, ему нужна кратковременная помощь эксперта. Но, если человек обучаем, обычно это не проблема. Физики и математики и лингвисты в среднем обучаемы.



Да, вывод. Дело в том, что знание того, что не должен знать сферический прикладной программист не даёт ключевого преимущества. Оно даёт только расширение возможной области деятельности в те области, где эти специфические знания нужны. Там действительно могут быть бОльшие зарплаты -- но скорее потому, что подходящих людей меньше, а не потому что они чем-то "более лучшие" программисты.

Т.е. на данный момент программистов толком нечему учить. Программу заполняют всякими как-то косвенно относящимися к делу вещами... И это лучше чем ничего, конечно. Но в целом печально.

Если бы я учил программистов, я бы постарался дать им опыт работы над сильно разными проектами из сильно разных областей. Тогда они могли бы по крайней мере действительно выбирать любую область работы. И даже работать в сложных случаях, когда требуется одновременно аж два знания из разных областей. И это да, некоторое практическое преимущество, возможность сменить работу на совсем другую, знакомство с разными паттернами, применяемыми в разных областях. Может даже количество перейдёт в какое-то качество, хотя это и не очевидно.

Да, и я думаю, программирование через некоторое время выйдет из этого странного промежуточного состояния. Например, останется 1% "программистов" от сегодняшнего, а остальное будет настолько упрощено, что с задачами прикладного программиста будут справляться пользователи без подготовки вообще.

May. 18th, 2009

12:48 am - Теория

Почувствовал пользу от теории :) Весьма, гм, специфическую.

Был у нас такой предмет "Перспективные микропроцессоры", вёл его Юрий Евгеньевич Шейнин. Рассказывал про конвейеры, кеш, предсказание переходов, векторные инструкции, VLIW прочее подобное. Мужик он умный, знает много, рассказывал интересно. Да и материал благодатный: это как раз тот случай, когда нужно понимать логику архитекторов, т.е. думать головой.

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

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

А теперь посмотрим, как эта общая образованность мне пригодилась.

Я сейчас читаю доки по POWERx/PowerPC. И там довольно много пишут про кеши, конвейер, переходы и т.п. И благодаря тому, что я в курсе, что это такое, я понимаю, что по сути ничего особенного они не пишут :) Так вот, поинт в том, что развив здоровый пофигизм в отношении непонятных деталей, интуицию и уверенность в себе, этого результата можно было бы достичь и без теории вообще :) Более того, в 99% случаев можно и без интуиции.

При этом я-то как раз подобные штуки очень люблю. Мне только волю дай -- буду сидеть и разбираться, как оно работает, сам ничего не делая :) Но я отношу это на счёт своих психологических комплексов и стараюсь себя как-то контролировать.

Upd: Как обычно, в комментах пришёл к сути того, что хотел сказать.

Я не против таких курсов, прикольно быть образованным. Я просто отмечаю сугубую не обязательность подобного образования. И низкую практическую эффективность в плане подготовки инженера.

Как заметил многоопытный [info]lumag, существуют ситуации, когда подобные знания оказываются полезны. И тут я не могу с ним спорить. Но, на мой взгляд, проблема в том, что в таких ситуациях знаний оказывается нужно гораздо больше, и более конкретных: не про вообще, а про вот этот вот процессор. Конечно, владение общим контекстом облегчает задачу получения конкретных знаний. Но по идее, можно и этот контекст изучить тогда, когда понадобится, благо в данном случае всё вполне тривиально, всего пара идей на всю индустрию.

Да, и конечно, общее образование полезно, и мозги развивает, и вообще. Но, может быть, это не самый эффективный способ расходования [учебного] времени?

Я правда не знаю. Общие слова про расширение кругозора и сознания я и сам могу сказать. И мне тоже кажется, что это важно. И я сам этим для себя занимаюсь. Но мало ли чем я занимаюсь. У есть некоторые сомнения в собственной адекватности, так что это не аргумент. Ещё у меня нет никаких экспериментальных данных, и я даже не знаю, какие измерения могли бы решить проблему, т.е. нет даже никаких конкретных утверждений. Есть пока только вот такие вот смехуечки над практической полезностью теории :)

Upd2: В данном случае в кои-то веки вопрос не "что мне пригодилось из того, чему нас учили", а что-то типа "мог бы я освоить это без отрыва от производства, если бы мне понадобилось". Если ответ "да", то допвопрос: "насколько и куда это расширяет поле моей возможной деятельности". Если ответ "да в общем-то и никуда особенно", то "для чего мне это изучать сейчас". Вот с этих позиций.

May. 7th, 2009

12:16 pm - Виртуальная память - 1 (дополнение)

Предыдущая часть тут.

Intel x86 (32-битные): дополнительные главы


Описанные до сих пор возможности относятся примерно к 486-му. Но прогресс не стоит на месте! Иначе же не впарить лохам новые процессоры. Много нового и интересного было реализовано инженерами Intel в последующих поколениях x86.

Глобальные страницы (начиная с Pentium Pro)

Начнём с простого. На картинках, изображавших PTE и PDE серым цветом был закрашен 8-й бит. Сорвём же покров.

Сорвём же, сорвём же! )

Пробиваем барьер 4 Гб: зачем и как

Сначала рассмотрим постановку задачи. Проблема в том, что линейный адрес у нас по прежнему 32 бита. А, поскольку для нормальной работы приложений преобразование линейного адреса в физический должно быть однозначным, больше чем в 32 бита его преобразовать не получится. И зачем нам тогда 36 разрядов на шине и 64 Гб памяти?

Затем, что преобразование действительно должно быть однозначным, но может быть переключаемым. И есть два основанных на этом юз-кейса:

  • Посредством каких-нибудь ОС-специфик заклинаний пользовательский процесс может попросить ОС отобразить часть его адресного пространства куда-нибудь в другое место в ОЗУ. Поработать там, а потом переключиться обратно. А потом ещё раз обратно. А потом ещё куда-нибудь... Так, манипулируя отображением на разные части ОЗУ, можно делать вид, что много-много памяти доступно почти напрямую. Очень неудобно, но куда деваться на 32-х разрядном процессоре. В Windows есть система соответствующих заклинаний.

  • Менее извращённый вариант. По 64-м доступным гигибайтам можно распределить разные процессы. Переключение будет происходить естественным образом при переключении контекста. Больше данных влезет в ОЗУ, будет меньше свопинга и больше счастья, и всё абсолютно прозрачно для приложений. Это умеют все уважающие себя ОС.

Перейдём к вопросу "как". В рамках существующей схемы преобразований адресовать 64 Гб нам мешают только слишком короткие адреса в CR3, PDE и PTE. С PDE и PTE всё должно быть понятно, а регистр CR3 я вам раньше не показывал. Вот он какой (до решительных изменений):

4.10 КБ

На адрес отведено 20 бит, именно поэтому каталог страниц должен быть выровнен по границе 4 Кб.

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

.. нет, не значит :) На процессоре жизнь не заканчивается. Проблемы с поддержкой адресов старше 4 Гб могут быть у всякой периферии в режиме DMA. Ну и у драйверов, соответственно. Вот немного на эту тему. Но не будем о грустном.

Пробиваем барьер 4 Гб - I (начиная с Pentium Pro)

Очередной флаг из регистра CR4 называется Physical Address Extension (PAE, бит 5). И он всё меняет.

и что же теперь? )



Всё, вроде про виртуальную память в x86 больше сказать нечего :) Нас ждёт PowerPC.

12:15 pm - Виртуальная память - 1

Пора платить долги. Теоретическое введение было тут. Перейдём к реализации.

Вам не повезло. Или наоборот -- повезло. Как посмотреть. В общем, тему защищённого режима x86 я знаю довольно туго. Поэтому получилось длинно, подробно и с кучей ссылок свои на собственные статьи :) Вот только код пока заленился писать. Придётся, конечно, но чуть позже.

Разбил на две части, иначе как-то многовато, слишком высока вероятность, что не прочитает никто :)


Intel x86 (32-битные)


Про устройство памяти в защищённом режиме Intel x86 с отключенной страничной адресацией я подробно писал тут.

Внимательный читатель мог заметить, что я переполз на народ-ру. Это связано с тем, что писем-нет сошёл с ума. Переполз буквально недавно, пока частично и коряво. Когда-нибудь (ха-ха) сделаю это менее коряво. А ещё мне хочется всё нафиг переписать, но тоже, видимо, чуть позже.

Кратко напомню основные тезисы.
  • Адрес, выставляемый процессором на системную шину называется физическим. В рассматриваемой серии Intel x86 максимум -- 36-и разрядов. Для краткости "физическое адресное пространство" я буду по бытовому называть "ОЗУ".

  • Адреса, которые используют прикладные программисты -- логические, имеют форму <сегмент>:<смещение>. Смещение -- 32 разряда.

  • Логические адреса преобразуются в линейные, по формуле <база сегмента> + <смещение>. В типичной современной ОС базы типичных сегментов -- 0 (могут быть специальные сегменты, например сегмент FS в Windows NT). Линейный адрес тоже ограничен 32-я разрядами (да, действительно можно устроить переполнение).

  • Линейные адреса преобразуются в физические. Если страничная адресация отключена, то <физический> = <линейный>. Если включена, то начинается то, ради чего мы тут собрались :)

Итак, табличная адресация включена.

а дальше? )



На этом мы завершили основную стройную картину. Дальше -- всякие подробности.

Mar. 5th, 2009

10:51 am - Виртуальная память - 0

Скорее всего, все знают, как устроена виртуальная память в Intel x86 ...

Не. Это вряд ли.

Скорее всего, многие видели картинки, более-менее изображающие устройство виртуальной памяти в Intel x86. Как выясняется, есть и другие забавные и поучительные варианты того же самого.

Это должен был быть один большой пост. Но он получается слишком большой и я его уже пишу слишком долго. Поэтому пусть будет много маленьких.

[Ликбез] Виртуальная память: что это и зачем

Вдруг кто-то не знал или забыл.

Итак: процессор, память, многозадачная операционная система, много задач (ака процессов). У каждого процесса есть какой-то исполняемый код, какие-то данные, чтобы всё это работало оно должно находиться в памяти. И тут возникает несколько проблем:
  • Процессы не должны мешать друг другу. В частности один процесс не должен иметь возможность случайно поменять данные/код другого процесса, иначе из-за ошибок в одном процессе будут падать все остальные (если такая возможность нужна, пусть попросит явно, это отдельный разговор).

  • Памяти мало. Всем сразу не хватает.

  • Памяти мало. А она ещё и фрагментируется. Допустим, загрузили процесс в память, за ним загрузили следующий, потом первый выгрузили. Осталась дырка. Эту память можно использовать только если будет загружаться процесс, по размеру не превышающий первый.

  • Вообще, "размер процесса" понятие очень условное. Память выделяется из кучи, памяти нужно то мало, то много, дать процессу один кусок навсегда -- очень не гибко

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

Для всего этого придумали сегментную виртуальную память, но она не удобным образом решала не все проблемы. Поэтому ещё немного подумали и придумали страничную виртуальную память. Это было настолько давно, что даже старики уже помнят только последнюю. И когда говорят "виртуальная память" имеется ввиду именно она. Но я начну свой рассказ с начала.

Сегментная виртуальная память

Сегментная виртуальная память требует сегментной адресации.

Простите, но что это такое я описывать не буду. Длинно, нужно рисовать картинки, не очень важно, да и по ходу разберётесь.

Т.е. процесс использует свои сегменты и в чужие не лезет. Это не сложно, это проверяется на уровне сегментных регистров: при попытке использовать сегмент, который нельзя, ОС получает тревожный сигнал (ака исключение), а процесс получает по башке (например, segmentation fault). Этим отличается защищённый режим от реального.

Термины реальный и защищённый режим вообще-то относятся к x86. В данном случае я применяю их нестрого, отношу к "защищённому режиму" те возможности, которые необходимы для реализации многозадачной ОС и которых не было в реальном режиме x86.

Это решение первой проблемы, но это ещё не виртуальная память.

Тут важно отметить, что процесс адресует память относительно начала сегмента, а где это начало он, по хорошему, понятия не имеет. А если имеет, то это ошибка проектирования ОС: не должен. Это ещё одно отличие защищённого режима от реального. А виртуальная память начинается с того, что ОС может временно выгрузить какой-то сегмент процесса из памяти, а когда этот сегмент опять понадобится процессу -- снова загрузить, возможно -- в другое место физической памяти (это термин; да, вот такое странное представление о физике).

Ну, допустим, как-то так:
  • Есть редко работающий процесс. Например, он отзывается на какие-то внешние события, типа прихода данных из сети.

  • ОС частично выгружает его из памяти. Содержимое сегментов данных этого процесса сохраняются на диске в специальном файле, сами сегменты помечаются как выгруженные (в таблице сегментов), занимаемая ими память -- как свободная (ОС должна где-то помнить, что у неё занято, а что свободно).

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

Кто понимает, почему x86 не может так работать -- респект и уважуха :) Ну да, там всё будет немного сложнее, но это уже будет глубокий оффтопик.

Таким образом, выгружая и загружая, можно выполнять больше процессов, чем у нас памяти. Более того, разные процессы могут ссылаться на один и тот же сегмент кода, значит можно и сэкономить. Сложно с:
  • динамическим выделением памяти (в принципе решаемо, но тяжело)

  • фрагментацией физической памяти (хотя сегменты и можно перемещать, это довольно затратно)

Но главное -- это очень грубый инструмент, с низкой разрешающей способностью. Можно выгрузить/загрузить только целый сегмент, это много.

Страничная виртуальная память

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

Итак, процессу предоставляется виртуальное адресное пространство (ВАП), каждому своё. Оно большое. По нонешним прогрессивным временам адресуемая область от 0 до 264-1, недавно стандартом было от 0 до 232-1. Это много, особенно если учесть что процессов не один, а физической памяти, скажем, 256 Мб, т.е. даже на одного не хватает.

Но оно на то и большое, чтобы быть с запасом. Считается, что большая его часть никогда не понадобится большей части процессов. Т.е. в этом огромном ВАП есть небольшие островки используемой памяти. Процесс может запросить себе дополнительный островок, или отпустить какой-то из используемых... Речь не про ограничения, расчёт именно на то, что их на самом деле не нужно слишком много.

Дальше, ВАП разбито на небольшие блоки одинакового размера. К примеру, по 4096 байт. И на такие же блоки разбита физическая память. Блоки называются страницами.

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

Это и есть дополнительный уровень косвенности.

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

  • меньше дискретность

  • В пределах ВАП элементарно регулируется объём используемой памяти, с точностью до страницы можно помечать память как используемую или как неиспользуемую процессом.

Что ещё интересного нужно отметить в этом красивом решении:
  • Адресное пространство других процессов оказывается за пределами языка. Оно просто не адресуемо, нет таких адресов, которые ссылаются на другой процесс. Чтобы как-то читать/писать в память других процессов нужно специально думать.

  • При попытке обратиться к неиспользуемой памяти, процесс тоже получит от ОС по башке.

To be continue... Следующая серия про x86, а дальше начнётся что-нибудь более интересное

Jan. 20th, 2009

04:23 am

Наконец начал статью про КС-грамматики и парсеры.

Я в курсе, что про это не писал только ленивый. Но:
-- мне процесс важнее "практической полезности результата"
-- я думаю, у меня получится лучше :)


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



Рассматриваем любимый всеми калькулятор. Грамматику на сложение-умножение можно записать так:

E --> T + E | T
T --> I * T | I
I --> (E) | number | name

Замечательная LL(1) грамматика, разбирается на ура, строит адекватное дерево, всё работает.

Дальше, понятно, почему вот такое:

E --> T + E | Т - E | T
T --> I * T | I / T | I
I --> (E) | number | name

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

2 - 1 + 1

она построит дерево

   -
 /   \
2     +
     / \
    1   1

А это не то, что нам нужно. Стандартный подход заключается в том, что грамматика переписывается в духе

E --> E + T | E - T | T
T --> T * I | T / I | I
I --> (E) | number | name

Получается совсем не LL(1) грамматика, и вроде даже вообще не LL. Разбирать её плохо. При написании парсера ручками, методом рекурсивного спуска, функции для разбора E и T пишут не "по грамматике", а "по пониманию".

Мне в голову пришёл несложный трюк, позволяющий сохранить LL(1). Для этого мы меняем язык, вводя две дополнительные унарные операции: минус и инверсию.

E --> T + E | Т - E | T
T --> I * T | I / T | I
I --> (E) | number | name | -I | %I

А встречая бинарный минус парсер преобразует его в бинарный плюс и унарный минус. Т.е.

2 - 1 + 1 = 2 + -1 + 1

и тут любое дерево нас устраивает, т.к. остались только ассоциативные операции. Аналогично с делением.



Внимание вопросы:
-- кто-то это придумал до меня? :), может даже есть специальное название? Или просто где-то описано? (я уверен, что тут я не первый, но интересны подробности..)
-- насколько это вообще нормально, что парсер в процессе работы меняет входной поток? Хотя в данном случае можно было это поручить отдельному препроцессору, т.к. замены на уровне регулярных выражений.
-- может какие-то комментарии? Что так не всё можно преобразовать я уже знаю...

Dec. 15th, 2008

09:14 am - Всё украдено до нас...

Готовя предыдущий пост я прочитал и просмотрел некоторое количество древних манускриптов, ссылки на них приведены там и немного тут... Короче, я в шоке.

Как в любом толковом магическом романе: уровень знаний древних потрясает. V и QuickSilver разработаны в конце 80-х. Это распределённые ОС с микроядром, поддерживающие многопоточность и миграцию процессов между машинами. QuickSilver и этого мало, в ней встроенные транзакции.

Для сравнения: MS Windows 1.0 вышла в 1985-м. Windows 3.0 в 1990-м. Это были убогие оболочки поверх ОС реального режима. С невытесняющей многозадачностью... Короче, каменный век. Микроядро это всё ещё "перспективное направление". Транзакции? О чём это вы? :) Распределённая ОС, миграция процессов? Ненененене.

Справедливости ради: первая ОС защищённого режима для PC появилась в 1985-м, это была OS/2 1.0. Но я не столько про PC, сколько про мейнстрим.

Однако, смотрим дальше. Из The V Distributed System:

The basic notion of an operating system kernel that only provides an interconnection mechanism for connecting applications to service modules, and avoids implementing the services directly is quite old (выделено мной; уже тогда "quite old", статья написана 20 лет назад, ага -- С.Х.). For instance, Brinch-Hansen [5] developed such a system, the RC 4000, in the late 1960s....

Т.е. первые ОС на микроядре появились где-то в конце 1960-х, by Per Brinch Hansen. Они не были распределёнными... потому что тогда ещё сетей толком не было. Ethernet придумали в 70-х. Цитированный абзац заканчивается вот так:

... This system, one of the first academically reported message-based systems, was characterized by an elegant design and problematic performance. Other systems followed, including Thoth [9, 14], DEMOS [3] and Accent [28], but performance remained a key concern.

Систем на микроядре к тому моменту было разработано с десяток. Производительность... Да, я помню про неё, чуть позже к этому вернёмся.

Упомянутый Per Brinch Hansen был главным редактором книги Classic Operating Systems (надо надыбать где-нить текст, кстати), на амазоне можно заглянуть под обложку, там есть оглавление. Это сборник статей про операционные системы. По разделам: Batch processing, Multiprogramming, Time sharing, Concurent programming, Personal computing, Distributed systems. Самая поздняя статья датирована 1990-м. Предыдущая -- 1983-м. Две самые ранние -- 1961-м.

Я чувствую себя варваром, наткнувшимся на пирамиды. В области операционных систем уже 40 лет назад они умели всё, что умеем мы, а 20 лет назад они сделали шажок вперёд и обогнали нас ещё лет на 20. Они бы сделали это раньше, но тогда ещё сетей не было.

Есть ощущение, что так везде в IT. Как только появляется новое поле экспериментов, академики в институтах лет за пять перепахивают его вдоль и поперёк, достигают при этом всех возможных принципиальных результатов. И потом медленно-медленно индустрия всё это осваивает. Что-то осваивается хорошо, что-то -- плохо... Но это именно процесс постепенного переваривания заглоченной туши. Нового оно не хавает, всё уже заглочено и записано, можно посмотреть в отчётах... А все ежеполугодно появляющиеся "новые технологии" -- просто рябь на воде. Или ещё один наконец переварившийся кусочек, или вообще те же яйца только чуть-чуть повёрнутые под другим углом. На самом же деле не меняется практически ничего. Убедительных примеров обратного в голову не приходит. Lisp, кстати, недавно праздновал полтинник.

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

Флеймогонность вопроса о том, начиная с какого момента решение "принципиально" или "существенно" новое мне вполне очевидна. Но на данный момент моё мнение вот такое.



Что ещё можно почитать-посмотреть. Несколько работ David R. Cheriton:
Thoth, a Portable Real-Time Operating System
UIO: A Uniform I/O System Interface for Distributed Systems
RFC 1045. VMTP: Versalite Message Transaction Protocol

И несколько работ Per Brinch Hansen:
http://brinch-hansen.net/papers/

Я на всё это только глянул, может потом руки дойдут.

09:07 am - Другие потоки

Во-первых, не stream, но thread. Называть их нитями я пока не привык, хотя это, видимо, не за горами. Во-вторых они и тут немного другие, про такие threadы вы, скорее всего, не слышали.

Читаю сейчас книжку Юреша Вахалия Unix изнутри. Не слишком полезно: половину я более-менее и так знаю, 95% никогда "в жизни" не пригодятся... Но иногда очень интересные вещи попадаются. Конечно, из того, что не пригодится :) Вот одна из них.

Три года назад Дима Голубев подарил эту книжку мне на день рождения по моей же просьбе, вот, руки дошли :) Кстати, по ссылке на сайте Питера очень ругают перевод. Ну не знаю, вообще, понять что имелось ввиду пока всегда было можно. Но английский вариант на всякий случай скачал.

Все представляют, как устроены стандартные виндовые/юниксовые потоки? Что для нас сейчас важно -- наличие двух стеков: для пользовательского режима и для ядра (кто не знает зачем это -- вот :)). Ну, вполне естественное решение. Поток живёт какой-то своей жизнью, сохраняет что-то в пользовательском стеке, когда переключается в режим ядра -- точно так же, никакой разницы. Логичный и простой вариант. Вахалия называет это моделью процесса.

Модель прерываний )
Продолжения )

Dec. 7th, 2008

06:35 am - Лики памяти

Просто подумалось. Программисты поймут :)

Oct. 24th, 2008

07:52 am - HOWTO: Свой поток ввода-вывода, beta-1

Коллеги, я опять написал статью и мне опять нужна ваша помощь.

Кто ещё С++ помнит, прочитайте пожалуйста. Статья не маленькая, но вроде простая как две копейки. Про то, как коварным наследованием подчинить себе iostream и использовать его в своих гнусных целях.

HOWTO: Свой поток ввода-вывода

Статья ещё не опубликована, так что просьба не выносить ссылку далеко. Давайте считать, что у неё TTL=2. И не забывайте вычитать.

Отзывы нужны любые, от "ничего не понял, ужасно" до "всё понял, ужасно" через "ну, типа, нормально, чё говорить-то". Я автор мнительный, в себе не уверенный, в собственной нормальности сомневающийся, сторонние подтверждения мне важны.

Более-менее осознанно я сам смогу читать статью только где-то через неделю, сейчас я ещё в горячке, так что ни один здоровый человек этого пока не читал.

Upd: Возможно, не совсем понятно, что я хотел. Все знают высказывание "дай человеку рыбу - накормишь его сегодня, дай ему удочку - накормишь на всю жизнь"? Мне мало даже этого, я хочу научить делать удочки.

Если рыба это конкретный код, удочка - знания, позволяющие написать такой код, то я хотел показать, откуда эти знания берутся. В результате статья это не задача-решение, а задача-процесс поиска решения.

Конечно, можно было бы всю первую часть заменить словами "basic_istream использует класс basic_streambuf в качестве источника данных". И какая разница, откуда я это знаю, может мне это приснилось, или ко мне было откровение, явился ангел с трубой и т.п.... Ну вот как-то хотелось попробовать другую форму подачи информации.

Upd2: Чуть-чуть обновил, лежит там же. Второй раз читать смысла нет. Изменения:
- примечание к _Read_s (где-то тут)
- совет после basic_buffered_istreambuf (чуть вверх отсюда)
- последний эпиграф стал менее прямолинейным :)

Upd3: Окончательно обнаглел. Добавил в начало абзац:

Конечно, я уже знаю «правильный ответ», и мог бы объяснить его как-нибудь короче, понятнее и систематичнее… Но мне кажется более интересным провести вас тем же путём, которым шёл я сам, по сторонам открываются потрясающие виды. Следуйте за мной.

Ай да я, ай да Пушкин. Делать вид, что я пишу технические статьи с каждым разом всё труднее.

Upd4: Удивительно, но народ не жалуется. Хм. Тем временем, следующее обновление. Из заметного:
- поменялся конец раздела про обобщённые символы, теперь там немного больше полезной информации.
- мне объяснили, откуда взялось имя eback, я описал это в статье.

Oct. 22nd, 2008

04:29 pm - Дожили

Никогда не понимал скриптов

# В URL что-то типа "http://server1.server2.yandex.ru/path/file.xml"

URL_HOST=`echo $URL | sed 's/^http:\/\///' | cut -d / -f 1`
URL_PATH="/"`echo $URL | sed 's/^http:\/\///' | cut -d / -f 2-`

printf "GET $URL_PATH?type=5&xmldata=test HTTP/1.1\r\nHost:$URL_HOST\r\n\r\n" | nc $URL_HOST 80


Удивительно, что я это не только понимаю, но и сам написал :)

Sep. 15th, 2008

11:46 pm - Теория вычислений, программа, beta-1

Чему я буду учить детей весной, если дело выгорит (громко не ржать!):

Вступительное слово )

Программа

ЛекцийСамостоятельно
Конечные автоматы
1. Детерминированные конечные автоматы.
2. Недетерминированные конечные автоматы.2
3. Преобразование НКА в ДКА
4. Алгоритм минимизации ДКА.24
Регулярные выражения
5. Определение, основные свойства.
6. Преобразование регулярного выражения в НКА2
7. Стандартные расширения языка регулярных выражений. Утилиты grep, flex, регулярные выражения в Python.2
8. Реализация лексического анализатора
9. Лемма о накачке.24
Контекстно-свободные грамматики
10. Определение, основные свойства.
11. Атрибутные грамматики2
12. Алгоритм разбора рекурсивным спуском.2
13. LL- и LR-грамматики, алгоритмы разбора.4
14. Инструменты antlr и bison4
15. Лемма о накачке для КС-грамматик 4
Машины Тьюринга
16. Определение, основные свойства, теоретическое значение.
17. Варианты машин Тьюринга, преобразования между ними2
18. Разрешимые, перечислимые, неперечислимые множества. Проблема останова.2
19. Классы сложности P, NP, PSPACE.24
Курсовой проект416


Немного подробнее, тем же весёлым языком )



На данный момент половину программы я представляю себе довольно ясно, а половину - довольно смутно... К счастью, впереди ещё вся осень и почти вся зима. "Самостоятельно" - это домашние задания, пока планирую по штуке на раздел. Ну и курсовик, конечно. 4 часа лекций на курсовик - устроим публичную защиту.

Более подробного плана пока в природе не существует.

Мысли-предложения?

Aug. 22nd, 2008

04:53 am - Пирамиды

Когда-нибудь это будет маленькая но гордая статья, пока - так.

Ты моя мумия, я твоя пирамида


Пирамида это дерево. Не обязательно двоичное - любое. Листья и узлы это некие "элементы", на которых определены операции сравнения (<>=). И единственное условие на пирамиду - узел должен быть меньше-или-равен каждого из своих детей.

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

По английски такая структура данных называется heap, ну и сортировка - heapsort. Всем известно, что heap это куча. Но, в данном контектсте перевод "пирамида" неплохо подходит и более-менее устоялся.

..ну и что у них внутри?.. )

Aug. 6th, 2008

06:43 am - Криптографические хеш-функции -II

Коллизии это здорово, но обращать функции - гораздо круче. Особенно если в истинную веру. Как это эффективно сделать, в 1980 году придумал человек с говорящей фамилией Хеллман.

Мартин Хеллман, да, это тот самый Хеллман, который вместе с Диффи. Кстати, недавно смотрел забавный фильм про его молодость. Мужик зажигал! Но, став отцом, видимо, пересмотрел взгляды на жизнь и двинул в науку.

Компромисс время-память (Time-Memory trade-off)

Оригинальная статья: A Cryptanalytic Time - Memory Trade-Off

Задача

Мы заранее знаем функцию h. Мощность её множества значений обозначим N.
Дано z: h(x) = z

x = ?

Решение "в лоб" требует O(N) попыток, это слишком много. Но, раз функция известна заранее, мы можем как-то подготовиться, что-нибудь такое вычислить и запомнить, а потом использовать... И опять, простое решение требует O(N) памяти и тоже не подходит.

Трепещите, неверные )

В следующей серии - про то, чем настоящие функции отличаются от оракулов. Сорвём же покровы.

Есть подозрение, что следующая серия подзадержится эдак на месяц. Сорри, дела.

Jul. 27th, 2008

08:05 am - Криптографические хеш-функции -I

Конспективное изложение курса, прочитанного Ильёй Мироновым в CSClub-е 17-18-24-го мая 2008.

Что такое хеш-функции я знал довольно давно... И именно поэтому Илья произвёл на меня огромное впечатление: оказалось, что там внутри куча интересных деталей, о которых я как-то никогда не задумывался. Давно хотел написать, но всё недосуг было. Исправляюсь. Предупреждаю: сначала всё очень просто, а потом всё очень интересно :)

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

Всё, что вы не хотели узнать про хеш-функции потому что не догадывались спросить. )

В следующем выпуске - чудеса обращения. Оставайтесь с нами!

Jun. 28th, 2008

01:15 am - Запятые продолжают плыть

Наконец победил лень и желание "сделать ещё как-то получше, хотя не понятно как, но вот что-то..". По результатам обсуждения статья "Плавающая запятая" наконец обновлена. Пока только у меня, но админу я новую версию послал, скоро, надеюсь и тут появится.

Нового кот наплакал: раздел Сравнения и ещё несколько мелочей. Хотелось больше, но как-то не получилось.

May. 15th, 2008

11:21 am - Эпиграф

Ядра - чистый изумруд

А.С.Пушкин о http://kernel.org


Не знаю, правда, к чему эпиграф: про линуксовые ядра я не знаю практически ничего и в ближайшем будущем не планирую. Кому надо - берите.

May. 12th, 2008

04:08 am - C++

Рок-н-ролл мёртв, а я ещё нет

Борис Гребенщиков

Мавр сделал свое дело, мавр может уходить

Фридрих Шиллер
(а вовсе не Шекспир, как я думал сначала)

Но он навсегда останется в нашей памяти...


Кучу всего разного хочется сказать про С++. Забавного и серьёзного. Начнём с забавного. Все помнят хохму про зависимость популярности языка программирования от бороды? Теперь посмотрите на домашнюю страничку Бъёрна Страуструпа и его новую фотографию... Есть ещё вопросы про C++0X? Вопросов нет, переходим к следующему пункту.

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

Что было


А недавно я прочитал



английская обложка красивее гораздо, так что пусть тут будет она :)

И зауважал Страуструпа ещё больше. Потому что он это тоже понимал, причём уже тогда, когда я ещё только рождался - как раз в 1982 году. При проектировании языка он, как Фома Аквинский, идёт срединным путём: между совместимостью с С, производительностью, гибкостью, новыми возможностями, абстракциями, ООП и низкоуровневым программированием. Не ударяется в крайности, но гнёт свою линию.

Мимо непокорных и нежных
Мимо этой и той стороны стекла
Мимо митьков и друидов
Мимо тех, кто может не пить


(c) http://www.aquarium.ru/discography/kunstkamer279.html#@992

С++ - язык, разработанный не просто так, ради идеи, а для живых людей и реальных задач. Это его слабость, но это же и его сила. Можно жаловаться, что что-то недостаточно высокоуровнево или продвинуто... Но при выборе любого другого варианта он разделил бы судьбу остальных замечательных языков того времени: Eiffel, Modula-3 - его использовало бы несколько сотен разработчиков по всему миру, остальным язык бы просто не подходил.

Потому что:
  • часто элементом задачи (или элементом очевидного оптимального решения) является «используя существующий код на …» Угадайте, на каком языке? На С, конечно; количество кода на других языках тогда было пренебрежимо мало по сравнению с С (ну, Фортран ещё, но Фортран из С/C++ использовать тоже можно, я даже сам как-то пробовал).

  • а вторым элементом так же часто бывает «и чтобы работало быстро!» Причём на тех машинах, не на современных. Причём не просто «быстро», а «не медленнее, чем на С»

  • третьим – необходимость писать код сегодня, а не переучиваться.

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

И мы до сих пор жили бы практически в каменном веке, с доминирующим С... И перейти с С на какую-нибудь Жабу программистам было бы на порядок труднее, это другое мышление совсем, и не родилась бы та Жаба. Но нам повезло - явился добрый гений :) И подумал наконец о людях и их потребностях, а не только о красоте идеи.

С++ должен был покрывать все перечисленные "потому что". И двигаться дальше – к вершинам абстракции. Очень широкий диапазон, и нижнюю границу никак нельзя поднять, иначе всё это бесполезно – язык просто не будет использоваться. Поэтому задрать верхнюю и отказаться от опасных механизмов не получается: в прикладном коде они опасные, а в системном – необходимые.

Подборка цитат из ДиЭС++ (цитирую по русскому изданию в серии "Классика Computer Scinse", в скобках в конце номер разделов, иногда мои комментарии):

  • В цифрах:

    За двенадцать лет число пользователей С++ в среднем удваивалось каждые семь с половиной месяцев. (7.1) --- закон Мура отдыхает! - С.Х.

    Компания Rational поставляет С++-версию библиотеки The Booch Components, которую Грейди Буч (Grady Booch) первоначально реализовал на языке Ada. На С++ её переписали сам Буч и Майк Вило (Mike Vilot). Версия на Ada занимает 125 тыс. строк исходного текста без учёта комментариев, на C++ - всего 10 тыс. строк. (8.4.1) --- Оцените прорыв в выразительности языка. И это без ущерба для эффективности! Так что сравнения с "квиксорт на Хаскеле в 2 строчки" не корректно - С.Х.

  • Цели и ограничения:

    С++ это язык, а не законченная система.[...] По своему замыслу С++ - это лишь один язык среди многих. (4.2)

    Не оставлять места языкам более низкого уровня, чем С++, исключая ассемблер (4.5)

    С++ проектировался как язык для системного программирования и разработки приложений, в которых есть большой системный компонент. (7.4.2)

    Если в компиляторы С++ не будет включён необязательный сборщик мусора, то в определенных областях С++ займёт невыгодные позиции, но я уверен, что такие компиляторы скоро появятся повсеместно. (9.3.2.2)

    C++ не является идеальным инструментом для приложений, где не нужны развитые системные компоненты, а требования к быстродействию и потреблению памяти не слишком жёсткие. Однако при поддержке со стороны библиотек и, возможно, сборщика мусора, он может найти применение и здесь. (9.3.2.5)

  • Случаи из практики )

  • Философское )

Главное, конечно, цели и ограничения. С++ не предназначен для того, чтобы на нём писать всё подряд, и Старуструп это понимал. Но на практике его мало кто слушал... Во всяком случае, на моей практике. Отступили от заветов :)

Чем сердце успокоилось


Мои основные претензии к С++ описаны здесь:

SH> Фокус в том, что правильно спроектировать библиотеку на C++ сложнее. ...
SH> Причина — С++ слишком заботится о байтах. О машинном представлении ...


Немного разверну.

В качестве "гарантированно переносимого" С++ предоставляет слишком низкоуровневые абстрации. Везде есть int, char, указатели. И, в общем, всё. Т.е., если библиотека хочет, чтобы её "понимали" все, она должна общаться с пользователем на языке, состоящем из int, char, указателей. Иначе это уже не просто библиотека, а, например, MFC-библиотека. Или ATL-библиотека. Или STL-библиотека. STL почти всем хороша, но её неудобно использовать из MFC-приложения..

Всё это усложняет совмещение нескольких библиотек, и/или фреймворков друг с другом. И написание "правильных" библиотек тоже усложняет.

Корни очевидны: широкий диапазон, нацеленность на системное программирование, прямую поддержку железа. Для подтверждения того, что подобные проблемы существуют и придуманы не мной - еще одна цитата из ДиЭС++:

Механизмы RTTI, которые предоставлялись разными библиотеками, были несовместимы между собой, и это стало препятствием для использования сразу нескольких библиотек. Кроме того, в каждом случае от проектировщика базовых классов требовалось многое предвидеть. Следовательно, был необходим какой-то механизм, который поддерживался бы самим языком (14.2)

Что будет


ДиЭС++ описывает период 1979 - 1994. 1998-й знаменит не только дефолтом, но и принятием стандарта С++, который, фактически, закрепил описанное в ДиЭС++ (ну и добавил кое-какие мелочи). Но на этом прогресс останавливаться не захотел, и через некоторое время комитет начал обсуждать следующую версию стандарта, названную C++0x. Подразумевалось, что стандарт выйдет где-то между 2001 и 2009 (и они ещё могут успеть! Хотя местами Страуструп шутит, что "X" не обязательно будет десятичной).

О будущем стандарте написана куча документов, текстов, есть мегабайты обсуждений в форумах, но я всё это не читал :) Я читал только Evolving a language in and for the real world: C++ 1991-2006 всё того же Страуструпа, ну и ещё кое что, о чём ниже. Несколько цитат:


В общем, очень познавательное чтение. Но, для того, чтобы понять, что же всё-таки войдёт в новый стандарт, его нужно немного дополнить.

Небезызвестный Герб Саттер мало того что работает в адской компании Майкрософт, так ещё и председательствует в комитете стандартизации С++. Просто страшно представить, сколько людей ежедневно посылают проклятия-и-пожелания в его адрес. Впрочем, человек он вроде хороший. Вот тут (01.11.2007) и тут (29.03.2008) он пишет про состоявшиеся заседания комитета. А тут даёт ссылку на документ State of C++ Evolution (Post-Bellevue 2008 Mailing) (Bellevue это город, где происходило заседание комитета в марте 2008), содержащий все принятые/ожидающие/отложенные и т.п. новшества (на текущий момент; следующее заседание в июле 2008, потом в сентябре 2008, следите за рекламой).

Подбивая бабки, по основным пунктам (тезисно, ориентируясь на Страуструпа, Саттера и заголовки документов, запарился читать все эти пропозлы, если честно; если где-то понял не так, буду благодарен за поправки):
  • Много внимания уделено улучшениям шаблонов. Собираются (пока не приняты, но они очень стараются, правда) добавить понятие "концепции" (concept), позволяющее явно вводить ограничения на типы параметров шаблона. Уже приняты псевдонимы для шаблонов (насколько я понимаю, параметризованный typedef, но мне лень было разбираться). Шаблоны с переменным количеством аргументов (не вкурил пока, как это)... Ещё что-то куда-то туда же.

  • Лямбда-функции. Гы :) Конечно, они получились "немного кастрированные" :) Если я не ошибся, то честных замыканий не получилось и вернуть лямбду в качестве результата работы функции нельзя. Ну, а чего ещё можно сделать в языке, который хранит локальные переменные в стеке. Но всё равно это немерянно круто, это расширяет использование всяких find_if и for_each до полного беспредела. Хотя это можно было и сейчас, т.е. это просто синтаксический сахар... Но сладенький :)

  • Поддержка многопоточности делится между языком и библиотекой. Что куда я не понял :) Страуструп пишет, что язык поддержит TLS (ещё не принят) и атомарные операции (уже приняты, там вроде написано про библиотеку, не вникал). А библиотека реализует интерфейс к потокам в стиле Windows/POSIX (в каком-то виде уже принята, опять же не разбирался). Ну и ещё есть как минимум один связанный вопрос, про исключения в соединённых (joined) потоках (тоже принят).

  • Сборки мусора, скорее всего, в этом стандарте не будет (но уже есть упоминания о C++1x).

  • Куча мелких полезных улучшений. Вывод типа значения функции, например.. "Мелких" в том смысле, что они не меняют подход к программированию, но снимают некоторые мешающие ограничения или упрощают синтаксис.

Чем сердце успокоится


Стандарт C++0x неплохой. Я боялся, что ребята свихнулись, а они вполне ещё крепкие старики :) Кроме шуток, когда я услышал про многопоточность и сборку мусора, я подумал, что комитет попытается охватить в одном языке всё, что можно... И это будет абзац, потому что в результате язык нельзя будет применять нигде. Оказалось - нет. Выпрыгнуть из штанов С++ не пытается. И я этому очень рад.

Но, имхо, доля системного кода снижается, доля критичного по скорости кода снижается, доля кода, для которого надёжность и простота важнее производительности повышается... С++ не уйдёт, скорее всего, никогда (ну, никогда это в ближайшие 10 лет :)). В своей области он лучший. Но вот область эта уменьшается. И новый стандарт её не расширяет (к счастью!), он улучшает язык, но оставляет без изменения задачи, для которых он предназначен (т.е. которые разумно решать с его помошью).

Кстати, кто хочет посмотреть на живого Страуструпа - Лекция в CSSlub-е университета Waterloo, август 2007. Изложение избранных мест из Evolving a language in and for the real world: C++ 1991-2006 на час с небольшим, потом полчаса ответов на вопросы. Ответы интересные.

May. 11th, 2008

03:40 am - ..на полях..

Пишу сейчас здоровый пост про С++ :) Читаю http://www.research.att.com/~bs/hopl-almost-final.pdf Наткнулся на такое:



4.1.8 Stepanov’s view
The description of the STL here is (naturally) focused on language and library issues in the context of C++. To get a complementary view, I asked Alexander Stepanov for his perspective [106]:

In October of 1976 I observed that a certain algorithm - parallel reduction - was associated with monoids: collections of elements with an associative operation. That observation led me to believe that it is possible to associate every useful algorithm with a mathematical theory and that such association allows for both widest possible use and meaningful taxonomy. As mathematicians learned to lift theorems into their most general settings, so I wanted to lift algorithms and data structures. One seldom needs to know the exact type of data on which an algorithm works since most algorithms work on many similar types. In order to write an algorithm one needs only to know the properties of operations on data. I call a collection of types with similar properties on which an algorithm makes sense the underlying concept of the algorithm. Also, in order to pick an efficient algorithm one needs to know the complexity of these operations. In other words, complexity is an essential part of the interface to a concept.

..more.. )

I am more optimistic about the long-term impact of Alex’s ideas than he is. However, we agree that the STL is just the first step of a long journey.



Слегка офигел. Не, я, конечно, понимал, что С++ разрабатывали не дураки. Но такой теоритической проработки - с Аристотелем, Эйлером, Кантором и моноидами - не ожидал :)

Navigate: (Previous 20 Entries)