Типобезопасность

Поделись знанием:
(перенаправлено с «Ошибка согласования типов»)
Перейти к: навигация, поиск
Типизация данных

Типобезопасность
Вывод типов
Статическая типизация
Динамическая типизация
Сильная и слабая типизация
Зависимые типы
Утиная типизация

В информатике типобезопасность (англ. type safety) языка программирования означает безопасность (или надёжность) его системы типов.

Система типов называется безопасной (англ. safe) или надежной (англ. sound), если в программах, прошедших проверку согласования типов, (англ. well-typed programs или well-formed programs) исключена возможность возникновения ошибок согласования типов во время выполнения[en]*[1][2][3][4][5][6].

Ошибка согласования типов или ошибка типизации (англ. type error) представляет собой несогласованность типов компонентов выражений в программе, например попытку использовать целое число в роли функции[7]. Пропущенные ошибки согласования типов на этапе выполнения[en]* могут приводить к багам и даже крахам[en] программ. Безопасность языка не является синонимом полного отсутствия багов, но, по меньшей мере, баги становятся исследуемы в рамках семантики языка (формальной или неформальной)[8].

Надёжные системы типов также называют сильными (англ. strong)[1][2], но трактовка этого термина часто смягчается, кроме того, его часто применяют к языкам, осуществляющим динамическую проверку согласования типов (см. сильная и слабая типизация).

Иногда безопасность рассматривается как свойство конкретной программы, а не языка, на котором она написана — по той причине, что некоторые типобезопасные языки разрешают обойти или нарушить систему типов, если программист практикует скудную типобезопасность. Распространено мнение, что такие возможности на практике оказываются необходимостью, но это вымысел[9]. Понятие о «безопасности программы» важно в том смысле, что реализация безопасного языка сама может быть небезопасной. Раскрутка компилятора решает эту проблему, обеспечивая языку безопасность не только в теории, но и на практике.





Подробности

Робин Милнер определил рамки типобезопасности слоганом:

Программы, прошедшие проверку типов, не могут «сбиться с пути истинного».

Робин Милнер[10]

Иначе говоря, безопасная система типов предотвращает заведомо ошибочные операции. Например, выражение 3 / "Hello, World" очевидно является ошибочным, поскольку арифметика не определяет операцию деления числа на строку. Формально, безопасность означает гарантию того, что значение любого выражения, прошедшего проверку типов, и имеющего тип τ, является истинным элементом множества значений τ, то есть будет лежать в границах диапазона значений, допустимого статическим типом этого выражения. На самом деле, в этом требовании есть нюансы — см. подтипы[en] и полиморфизм для сложных случаев.

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

Многие языки системного программирования (например, Ada, Си, C++) предусматривают ненадёжные (англ. unsound) или небезопасные (англ. unsafe) операции, предназначенные для возможности нарушить (англ. violate) систему типов — см. приведение типа и каламбур типизации. В одних случаях это допускается лишь в ограниченных частях программы, в других — неотличимо от хорошо типизированных операций[11].

В мейнстриме нередко встречается сужение понятия типобезопасности до «безопасности типов в отношении доступа к памяти» (англ. memory type safety), означающее, что компоненты объектов одного агрегатного типа не могут обращаться к ячейкам памяти, выделенным под объекты другого типа. Безопасность доступа к памяти означает запрещение возможности скопировать произвольную цепочку бит из одной области памяти в другую. Например, если язык предусматривает тип t, имеющий ограниченный спектр допустимых значений, и предоставляет возможность скопировать нетипизированные данные в переменную этого типа, то это не является типобезопасным, поскольку потенциально допускает, что переменная типа t будет иметь значение, не являющееся допустимым для типа t. И, в частности, если такой небезопасный язык позволяет записать произвольное целое значение в переменную, имеющую тип «указатель», то небезопасность доступа к памяти очевидна (см. Висячий указатель). Примерами небезопасных языков служат Си и C++[4]. В сообществах этих языков часто называют «безопасными» любые операции, непосредственно не приводящие к краху программы[en]. Безопасность доступа к памяти также означает предотвращение возможности переполнения буфера, например, попытки записи крупноразмерных объектов в ячейки, выделенные для объектов другого типа меньшего размера.

Надёжные статические системы типов консервативны (избыточны) в том смысле, что отвергают даже программы, которые исполнились бы корректно. Причина этого заключается в том, что для любого Тьюринг-полного языка, множество программ, которые могут порождать ошибки согласования типов во время выполнения, алгоритмически неразрешимо (см. проблема остановки)[12][13]. Как следствие, такие системы типов обеспечивают степень защиты, существенно более высокую, чем это необходимо для обеспечения безопасности доступа к памяти. С другой стороны, безопасность некоторых действий не может быть доказана статически и должна контролироваться динамически — например, индексация массива с произвольным доступом. Такой контроль может осуществляться либо рантайм-системой самого языка, либо непосредственно функциями, реализующими подобные потенциально небезопасные операции.

Сильно динамически типизируемые языки (например, Lisp, Smalltalk) не допускают повреждения данных за счёт того, что программа, пытающаяся преобразовать значение к несовместимому типу, порождает исключение. К достоинствам сильной динамической типизации перед типобезопасностью можно отнести отсутствие консервативности, и, как следствие, расширение спектра решаемых задач программирования. Ценой этого становится неизбежное снижение быстродействия программ, а также необходимость существенно бо́льшего количества пробных запусков для выявления возможных ошибок. Поэтому многие языки комбинируют возможности статического и динамического контроля согласования типов тем или иным образом.[14][12][1]

Примеры безопасных языков

Ada

Ada (наиболее типобезопасный язык в семействе Pascal) ориентирована на разработку надёжных встраиваемых систем, драйверов и других задач системного программирования. Для реализации критичных секций Ada предоставляет ряд небезопасных конструкций, имена которых обычно начинаются с Unchecked_.

Язык SPARK[en] является подмножеством Ады. Из него устранены небезопасные возможности, но добавлены возможности проектирования по контракту. SPARK исключает возможность возникновения болтающихся указателей[en] посредством исключения самой возможности динамического выделения памяти. Статически проверяемые контракты были добавлены в Ada2012.

Хоар в своей лекции на премию Тьюринга утверждал, что для обеспечения надёжности мало статических проверок — надёжность в первую очередь является следствием простоты[15]. Тогда же он предсказал, что сложность Ады станет причиной катастроф. Его предсказание сбылось в 1996 году — космическая ракета Ариан-5 взорвалась на 37-й секунде после старта. Детальный анализ результатов расследования показал, что корневой причиной произошедшей программной ошибки служила излишняя сложность спецификаций повторно используемых компонентов, которая не позволила программистам в полной мере проконтролировать диапазон возможных значений переменных в проверяемых ими кодах обработчиков исключений, окружающих умышленно небезопасные операции приведения типов[16][17].

BitC

BitC представляет собой гибридный язык, комбинирующий низкоуровневые возможности Си с безопасностью Standard ML и лаконичностью[en] Scheme. BitC ориентирован на разработку надёжных встраиваемых систем, драйверов и других задач системного программирования.

Cyclone

Cyclone является безопасным диалектом языка Си, заимствующим многие идеи из ML (включая типобезопасный параметрический полиморфизм). Cyclone предназначен для тех же задач, что и Си, и после осуществления всех проверок компилятор порождает код на ANSI C. Cyclone не требует виртуальной машины или сборки мусора для обеспечения динамической безопасности — вместо этого он основан на управлении памятью посредством регионов[en]. Cyclone устанавливает более высокую планку требований безопасности исходного кода, и из-за небезопасной природы Си портирование даже простых программ с Си на Cyclone может потребовать определённой работы, хотя немалая её часть может быть проделана в рамках Си до смены компилятора. Поэтому Cyclone часто определяют не как диалект Си, а как «язык, синтаксически и семантически похожий на Си».

Haskell

Haskell (потомок ML) изначально разрабатывался как полнотиповый чистый язык, что должно было сделать поведение программ на нём ещё более предсказуемым, чем на ранних диалектах ML. Однако, позже в стандарте языка были предусмотрены небезопасные операции[18][19], необходимые в повседневной практике, хотя и отмеченные соответствующими идентификаторами (начинающимися с unsafe)[20].

Haskell также предоставляет возможности слабой динамической типизации, и в стандарт языка была включена реализация механизма обработки исключений посредством этих возможностей. Её использование может приводить к аварийному завершению программ, за что Роберт Харпер[en] назвал Хаскел «исключительно небезопасным»[20]. Он считает неприемлемым тот факт, что исключения имеют тип, определённый пользователем в контексте класса типов[en]* Typeable, с учётом того, что исключения генерируются безопасным кодом (за пределами монады IO); и классифицирует выдаваемое компилятором сообщение о внутренней ошибке как несоответствующее слогану Милнера. В последовавшем обсуждении было показано, как можно было бы реализовать в Хаскеле статически типобезопасные исключения в стиле Standard ML.

Lisp

«Чистый» (минимальный) Lisp представляет собой однотиповый язык (то есть любая конструкция принадлежит к типу «S-выражение»)[21], хотя даже первые промышленные реализации Lisp предусматривали как минимум определённое количество атомов[en]. Семейство потомков языка Lisp представлено по большей степени сильно динамически типизируемыми языками, но существуют статически типизируемые и сочетающие обе формы типизации.

Common Lisp является сильно динамически типизируемым языком, но предусматривает возможность явно (манифестно[en]) назначать типы (а компилятор SBCL способен сам их выводить), однако, эта возможность используется для оптимизации и усиления динамических проверок и не означает статическую типобезопасность. Программист может установить для компилятора сниженный уровень динамических проверок с целью повышения быстродействия, и скомпилированная таким образом программа уже не может считаться безопасной[22][23].

Язык Scheme также является сильно динамически типизируемым языком, но компилятор Stalin[en] статически выводит типы, используя их для агрессивной оптимизации программ. Языки «Typed Racket» (расширение Racket Scheme) и Shen[en] типобезопасны. Clojure сочетает сильный динамический и статический контроль типов.

ML

Язык ML изначально разрабатывался в качестве интерактивной системы доказательства теорем, и лишь впоследствии стал самостоятельным компилируемым языком общего назначения. Много усилий было уделено доказательству надёжности параметрически полиморфной системы типов Хиндли-Милнера, лежащей в основе ML. Доказательство надёжности построено для чисто функционального подмножества («Fuctional ML»), расширения ссылочными типами («Reference ML»), расширения исключениями («Exception ML»), для языка, объединяющего все эти расширения («Core ML») и наконец, его расширения первоклассными продолжениями («Control ML»), сперва мономорфными, затем полиморфными[2].

Следствием этого стало то, что потомки ML зачастую априори считаются типобезопасными, даже несмотря на то, что некоторые из них откладывают значимые проверки на этап выполнения[en]* программы (OCaml), либо отклоняются от семантики, для которой построено доказательство надёжности, и содержат небезопасные возможности явным образом (Haskell). Для языков семейства ML характерна развитая поддержка алгебраических типов данных, использование которых существенно способствует предотвращению логических ошибок, что также поддерживает впечатление типобезопасности.

Некоторые потомки ML так же являются инструментами интерактивного доказательства (Idris, Mercury, Agda). Многие из них, хотя и могли бы использоваться для непосредственной разработки программ с доказанной надёжностью, чаще используются для верификации программ на других языках — из-за таких причин как высокая трудоёмкость использования, низкое быстродействие, отсутствие FFI[en] и прочее. Среди потомков ML с доказанной надёжностью выделяются как ориентированные на промышленное применение языки Standard ML и прототип его дальнейшего развития successor ML[24] (ранее известный как «ML2000»).

Standard ML

Язык Standard ML (старший в семействе языков ML) ориентирован на разработку крупномасштабных[en] программ промышленного быстродействия[25]. Язык имеет строгое формальное определение и его статическая и динамическая безопасность доказана[26]. После статической проверки согласованности интерфейсов компонентов программы (в том числе порождаемых — см. функторы ML), дальнейший контроль безопасности поддерживается рантайм-системой. Как следствие, даже содержащая ошибку программа на Standard ML всегда продолжает вести себя как ML-программа: она может навечно уйти в расчёты или выдать пользователю сообщение об ошибке, но она не может обрушиться[en][9].

Однако, некоторые реализации (SML/NJ[en], Mythryl[en], MLton) включают нестандартные библиотеки, предоставляющие определённые небезопасные операции (их идентификаторы начинаются с Unsafe). Эти возможности необходимы для внешнеязыкового интерфейса[en] этих реализаций, обеспечивающего взаимодействие с не-ML-кодом (обычно это код на Си, реализующий критичные по скорости компоненты программ), который может требовать своебразного битового представления данных. Кроме того, многие реализации Standard ML, хотя сами написаны на нём самом, используют рантайм-систему, написанную на Си. Другим примером является режим REPL компилятора SML/NJ[en], использующий небезопасные операции для исполнения интерактивно вводимого программистом кода.

Язык Alice является расширением Standard ML, предоставляя возможности сильной динамической типизации.

См. также

Напишите отзыв о статье "Типобезопасность"

Примечания

  1. 1 2 3 Ахо-Сети-Ульман, Статическая и динамическая проверка типов, с. 340.
  2. 1 2 3 Wright, Felleisen - A Syntactic Approach to Type Soundness, 1994.
  3. Cardelli - Typeful programming, с. 3.
  4. 1 2 Mitchel - Concepts in Programming Languages, 2004, 6.2.1 Type Safety, с. 132-133.
  5. 1 2 Java is not type-safe.
  6. Harper - Practical Foundations for Programming Languages, Chapter 4. Statics, с. 35.
  7. Mitchel - Concepts in Programming Languages, 2004, 6.1.2 Type Errors, с. 130.
  8. Appel - A Critique of Standard ML, Safety, с. 2.
  9. 1 2 3 Paulson - ML for the Working Programmer, с. 2.
  10. Milner - A Theory of Type Polymorphism in Programming, 1978.
  11. Cardelli - Typeful programming, 9.3. Type violations, с. 51.
  12. 1 2 Mitchel - Concepts in Programming Languages, 2004, 6.2.2 Compile-Time and Run-Time Checking, с. 133-135.
  13. Pierce, 1.1 Типы в информатике, с. 3.
  14. Cardelli - Typeful programming, 9.1 Dynamic types, с. 49.
  15. C.A.R. Hoare — The Emperor’s Old Clothes, Communications of the ACM, 1981
  16. [www.osp.ru/os/1998/06/179592/ Мифы о безопасном ПО: уроки знаменитых катастроф]
  17. M. Jezequel, B. Meyer «Put It in the Contract: The Lessons of Ariane», // Computer, Vol.30, No.2, January 1997, pp.129-130.
  18. [hackage.haskell.org/package/base-4.6.0.0/docs/Unsafe-Coerce.html unsafeCoerce] (язык Haskell)
  19. [hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html System.IO.Unsafe] (язык Haskell)
  20. 1 2 Haskell Is Exceptionally Unsafe.
  21. Cardelli, Wegner - On Understanding Types, 1985, 1.1. Organizing Untyped Universes, с. 3.
  22. [www.lispworks.com/documentation/HyperSpec/Body/d_optimi.htm Common Lisp HyperSpec]. Проверено 26 мая 2013.
  23. [www.sbcl.org/manual/#Declarations-as-Assertions SBCL Manual — Declarations as Assertions]
  24. [successor-ml.org/ successorML]
  25. Appel - A Critique of Standard ML.
  26. Robin Milner, Mads Tofte [www.itu.dk/people/tofte/publ/1990sml/1991commentaryBody.pdf Commentary on Standard ML]. — Universiry of Edinburg, University of Nigeria, 1991.

Литература

  • Robin Milner A Theory of Type Polymorphism in Programming. — Jcss, 1978. — Т. 17. — С. 348–375.
  • Stavros Macrakis [portal.acm.org/citation.cfm?id=1005937.1005941 Safety and power] // ACM SIGSOFT Software Engineering Notes. — 1982. — Т. 7, вып. 2, № April. — С. 25–26. — DOI:10.1145/1005937.1005941.
  • Luca Cardelli, Peter Wegner [lucacardelli.name/Papers/OnUnderstanding.A4.pdf On Understanding Types, Data Abstraction, and Polymorphism]. — ACM Computing Surveys, 1985. — С. 471-523. — ISSN [www.sigla.ru/table.jsp?f=8&t=3&v0=0360-0300&f=1003&t=1&v1=&f=4&t=2&v2=&f=21&t=3&v3=&f=1016&t=3&v4=&f=1016&t=3&v5=&bf=4&b=&d=0&ys=&ye=&lng=&ft=&mt=&dt=&vol=&pt=&iss=&ps=&pe=&tr=&tro=&cc=UNION&i=1&v=tagged&s=0&ss=0&st=0&i18n=ru&rlf=&psz=20&bs=20&ce=hJfuypee8JzzufeGmImYYIpZKRJeeOeeWGJIZRrRRrdmtdeee88NJJJJpeeefTJ3peKJJ3UWWPtzzzzzzzzzzzzzzzzzbzzvzzpy5zzjzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzztzzzzzzzbzzzzzzzzzzzzzzzzzzzzzzzzzzzvzzzzzzyeyTjkDnyHzTuueKZePz9decyzzLzzzL*.c8.NzrGJJvufeeeeeJheeyzjeeeeJh*peeeeKJJJJJJJJJJmjHvOJJJJJJJJJfeeeieeeeSJJJJJSJJJ3TeIJJJJ3..E.UEAcyhxD.eeeeeuzzzLJJJJ5.e8JJJheeeeeeeeeeeeyeeK3JJJJJJJJ*s7defeeeeeeeeeeeeeeeeeeeeeeeeeSJJJJJJJJZIJJzzz1..6LJJJJJJtJJZ4....EK*&debug=false 0360-0300].
  • Альфред Ахо, Рави Сети, Джеффри Ульман. Компиляторы: принципы, технологии и инструменты. — Addison-Wesley Publishing Company, Издательский дом «Вильямс», 1985, 2001, 2003. — 768 с. — ISBN 5-8459-0189-8 (рус.), 0-201-10088-6 (ориг.).
  • Лука Карделли[en] [www.lucacardelli.name/Papers/TypefulProg.pdf Typeful programming] ( (англ.)) // IFIP State-of-the-Art Reports. — Springer-Verlag, 1991. — Вып. Formal Description of Programming Concepts. — С. 431–507.
  • Andrew W. Appel [www.cs.princeton.edu/research/techreps/TR-364-92 A Critique of Standard ML]. — Princeton University, revised version of CS-TR-364-92, 1992.
  • Andrew K. Wright, Matthias Felleisen[en] [citeseer.ist.psu.edu/wright92syntactic.html A Syntactic Approach to Type Soundness] // Information and Computation. — 1992. — Т. 115, вып. 1. — С. 38–94. — DOI:10.1006/inco.1994.1093.
  • Lawrence C. Paulson. ML for the Working Programmer. — 2nd. — Cambridge University Press, 1996. — 492 с. — ISBN 0-521-57050-6 (твёрдый переплёт), 0-521-56543-X (мягкий переплёт).
  • Pierce, Benjamin C. [www.cis.upenn.edu/~bcpierce/tapl/ Types and Programming Languages]. — MIT Press, 2002. — ISBN 0-262-16209-1.
  • John C. Mitchell. [bookre.org/reader?file=463664 Concepts in Programming Languages]. — Cambridge University Press, 2004. — ISBN 0-511-04091-1 (eBook in netLibrary); 0-521-78098-5 (hardback).
  • Harper. [bookfi.org/book/1076504 Practical Foundations for Programming Languages]. — version 1.37 (revised 01.11.2014). — licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License., 2012. — 544 с.
  • Vijay Saraswat[en]. [www.cis.upenn.edu/~bcpierce/courses/629/papers/Saraswat-javabug.html Java is not type-safe].

Ссылки

  • [c2.com/cgi/wiki?TypeSafe Type Safe]. Portland Pattern Repository Wiki. Проверено 5 февраля 2014.
  • Robert Harper[en] [existentialtype.wordpress.com/2012/08/14/haskell-is-exceptionally-unsafe/ Haskell Is Exceptionally Unsafe].

Отрывок, характеризующий Типобезопасность



После столкновения при Вязьме, где Кутузов не мог удержать свои войска от желания опрокинуть, отрезать и т. д., дальнейшее движение бежавших французов и за ними бежавших русских, до Красного, происходило без сражений. Бегство было так быстро, что бежавшая за французами русская армия не могла поспевать за ними, что лошади в кавалерии и артиллерии становились и что сведения о движении французов были всегда неверны.
Люди русского войска были так измучены этим непрерывным движением по сорок верст в сутки, что не могли двигаться быстрее.
Чтобы понять степень истощения русской армии, надо только ясно понять значение того факта, что, потеряв ранеными и убитыми во все время движения от Тарутина не более пяти тысяч человек, не потеряв сотни людей пленными, армия русская, вышедшая из Тарутина в числе ста тысяч, пришла к Красному в числе пятидесяти тысяч.
Быстрое движение русских за французами действовало на русскую армию точно так же разрушительно, как и бегство французов. Разница была только в том, что русская армия двигалась произвольно, без угрозы погибели, которая висела над французской армией, и в том, что отсталые больные у французов оставались в руках врага, отсталые русские оставались у себя дома. Главная причина уменьшения армии Наполеона была быстрота движения, и несомненным доказательством тому служит соответственное уменьшение русских войск.
Вся деятельность Кутузова, как это было под Тарутиным и под Вязьмой, была направлена только к тому, чтобы, – насколько то было в его власти, – не останавливать этого гибельного для французов движения (как хотели в Петербурге и в армии русские генералы), а содействовать ему и облегчить движение своих войск.
Но, кроме того, со времени выказавшихся в войсках утомления и огромной убыли, происходивших от быстроты движения, еще другая причина представлялась Кутузову для замедления движения войск и для выжидания. Цель русских войск была – следование за французами. Путь французов был неизвестен, и потому, чем ближе следовали наши войска по пятам французов, тем больше они проходили расстояния. Только следуя в некотором расстоянии, можно было по кратчайшему пути перерезывать зигзаги, которые делали французы. Все искусные маневры, которые предлагали генералы, выражались в передвижениях войск, в увеличении переходов, а единственно разумная цель состояла в том, чтобы уменьшить эти переходы. И к этой цели во всю кампанию, от Москвы до Вильны, была направлена деятельность Кутузова – не случайно, не временно, но так последовательно, что он ни разу не изменил ей.
Кутузов знал не умом или наукой, а всем русским существом своим знал и чувствовал то, что чувствовал каждый русский солдат, что французы побеждены, что враги бегут и надо выпроводить их; но вместе с тем он чувствовал, заодно с солдатами, всю тяжесть этого, неслыханного по быстроте и времени года, похода.
Но генералам, в особенности не русским, желавшим отличиться, удивить кого то, забрать в плен для чего то какого нибудь герцога или короля, – генералам этим казалось теперь, когда всякое сражение было и гадко и бессмысленно, им казалось, что теперь то самое время давать сражения и побеждать кого то. Кутузов только пожимал плечами, когда ему один за другим представляли проекты маневров с теми дурно обутыми, без полушубков, полуголодными солдатами, которые в один месяц, без сражений, растаяли до половины и с которыми, при наилучших условиях продолжающегося бегства, надо было пройти до границы пространство больше того, которое было пройдено.
В особенности это стремление отличиться и маневрировать, опрокидывать и отрезывать проявлялось тогда, когда русские войска наталкивались на войска французов.
Так это случилось под Красным, где думали найти одну из трех колонн французов и наткнулись на самого Наполеона с шестнадцатью тысячами. Несмотря на все средства, употребленные Кутузовым, для того чтобы избавиться от этого пагубного столкновения и чтобы сберечь свои войска, три дня у Красного продолжалось добивание разбитых сборищ французов измученными людьми русской армии.
Толь написал диспозицию: die erste Colonne marschiert [первая колонна направится туда то] и т. д. И, как всегда, сделалось все не по диспозиции. Принц Евгений Виртембергский расстреливал с горы мимо бегущие толпы французов и требовал подкрепления, которое не приходило. Французы, по ночам обегая русских, рассыпались, прятались в леса и пробирались, кто как мог, дальше.
Милорадович, который говорил, что он знать ничего не хочет о хозяйственных делах отряда, которого никогда нельзя было найти, когда его было нужно, «chevalier sans peur et sans reproche» [«рыцарь без страха и упрека»], как он сам называл себя, и охотник до разговоров с французами, посылал парламентеров, требуя сдачи, и терял время и делал не то, что ему приказывали.
– Дарю вам, ребята, эту колонну, – говорил он, подъезжая к войскам и указывая кавалеристам на французов. И кавалеристы на худых, ободранных, еле двигающихся лошадях, подгоняя их шпорами и саблями, рысцой, после сильных напряжений, подъезжали к подаренной колонне, то есть к толпе обмороженных, закоченевших и голодных французов; и подаренная колонна кидала оружие и сдавалась, чего ей уже давно хотелось.
Под Красным взяли двадцать шесть тысяч пленных, сотни пушек, какую то палку, которую называли маршальским жезлом, и спорили о том, кто там отличился, и были этим довольны, но очень сожалели о том, что не взяли Наполеона или хоть какого нибудь героя, маршала, и упрекали в этом друг друга и в особенности Кутузова.
Люди эти, увлекаемые своими страстями, были слепыми исполнителями только самого печального закона необходимости; но они считали себя героями и воображали, что то, что они делали, было самое достойное и благородное дело. Они обвиняли Кутузова и говорили, что он с самого начала кампании мешал им победить Наполеона, что он думает только об удовлетворении своих страстей и не хотел выходить из Полотняных Заводов, потому что ему там было покойно; что он под Красным остановил движенье только потому, что, узнав о присутствии Наполеона, он совершенно потерялся; что можно предполагать, что он находится в заговоре с Наполеоном, что он подкуплен им, [Записки Вильсона. (Примеч. Л.Н. Толстого.) ] и т. д., и т. д.
Мало того, что современники, увлекаемые страстями, говорили так, – потомство и история признали Наполеона grand, a Кутузова: иностранцы – хитрым, развратным, слабым придворным стариком; русские – чем то неопределенным – какой то куклой, полезной только по своему русскому имени…


В 12 м и 13 м годах Кутузова прямо обвиняли за ошибки. Государь был недоволен им. И в истории, написанной недавно по высочайшему повелению, сказано, что Кутузов был хитрый придворный лжец, боявшийся имени Наполеона и своими ошибками под Красным и под Березиной лишивший русские войска славы – полной победы над французами. [История 1812 года Богдановича: характеристика Кутузова и рассуждение о неудовлетворительности результатов Красненских сражений. (Примеч. Л.Н. Толстого.) ]
Такова судьба не великих людей, не grand homme, которых не признает русский ум, а судьба тех редких, всегда одиноких людей, которые, постигая волю провидения, подчиняют ей свою личную волю. Ненависть и презрение толпы наказывают этих людей за прозрение высших законов.
Для русских историков – странно и страшно сказать – Наполеон – это ничтожнейшее орудие истории – никогда и нигде, даже в изгнании, не выказавший человеческого достоинства, – Наполеон есть предмет восхищения и восторга; он grand. Кутузов же, тот человек, который от начала и до конца своей деятельности в 1812 году, от Бородина и до Вильны, ни разу ни одним действием, ни словом не изменяя себе, являет необычайный s истории пример самоотвержения и сознания в настоящем будущего значения события, – Кутузов представляется им чем то неопределенным и жалким, и, говоря о Кутузове и 12 м годе, им всегда как будто немножко стыдно.
А между тем трудно себе представить историческое лицо, деятельность которого так неизменно постоянно была бы направлена к одной и той же цели. Трудно вообразить себе цель, более достойную и более совпадающую с волею всего народа. Еще труднее найти другой пример в истории, где бы цель, которую поставило себе историческое лицо, была бы так совершенно достигнута, как та цель, к достижению которой была направлена вся деятельность Кутузова в 1812 году.
Кутузов никогда не говорил о сорока веках, которые смотрят с пирамид, о жертвах, которые он приносит отечеству, о том, что он намерен совершить или совершил: он вообще ничего не говорил о себе, не играл никакой роли, казался всегда самым простым и обыкновенным человеком и говорил самые простые и обыкновенные вещи. Он писал письма своим дочерям и m me Stael, читал романы, любил общество красивых женщин, шутил с генералами, офицерами и солдатами и никогда не противоречил тем людям, которые хотели ему что нибудь доказывать. Когда граф Растопчин на Яузском мосту подскакал к Кутузову с личными упреками о том, кто виноват в погибели Москвы, и сказал: «Как же вы обещали не оставлять Москвы, не дав сраженья?» – Кутузов отвечал: «Я и не оставлю Москвы без сражения», несмотря на то, что Москва была уже оставлена. Когда приехавший к нему от государя Аракчеев сказал, что надо бы Ермолова назначить начальником артиллерии, Кутузов отвечал: «Да, я и сам только что говорил это», – хотя он за минуту говорил совсем другое. Какое дело было ему, одному понимавшему тогда весь громадный смысл события, среди бестолковой толпы, окружавшей его, какое ему дело было до того, к себе или к нему отнесет граф Растопчин бедствие столицы? Еще менее могло занимать его то, кого назначат начальником артиллерии.
Не только в этих случаях, но беспрестанно этот старый человек дошедший опытом жизни до убеждения в том, что мысли и слова, служащие им выражением, не суть двигатели людей, говорил слова совершенно бессмысленные – первые, которые ему приходили в голову.
Но этот самый человек, так пренебрегавший своими словами, ни разу во всю свою деятельность не сказал ни одного слова, которое было бы не согласно с той единственной целью, к достижению которой он шел во время всей войны. Очевидно, невольно, с тяжелой уверенностью, что не поймут его, он неоднократно в самых разнообразных обстоятельствах высказывал свою мысль. Начиная от Бородинского сражения, с которого начался его разлад с окружающими, он один говорил, что Бородинское сражение есть победа, и повторял это и изустно, и в рапортах, и донесениях до самой своей смерти. Он один сказал, что потеря Москвы не есть потеря России. Он в ответ Лористону на предложение о мире отвечал, что мира не может быть, потому что такова воля народа; он один во время отступления французов говорил, что все наши маневры не нужны, что все сделается само собой лучше, чем мы того желаем, что неприятелю надо дать золотой мост, что ни Тарутинское, ни Вяземское, ни Красненское сражения не нужны, что с чем нибудь надо прийти на границу, что за десять французов он не отдаст одного русского.
И он один, этот придворный человек, как нам изображают его, человек, который лжет Аракчееву с целью угодить государю, – он один, этот придворный человек, в Вильне, тем заслуживая немилость государя, говорит, что дальнейшая война за границей вредна и бесполезна.
Но одни слова не доказали бы, что он тогда понимал значение события. Действия его – все без малейшего отступления, все были направлены к одной и той же цели, выражающейся в трех действиях: 1) напрячь все свои силы для столкновения с французами, 2) победить их и 3) изгнать из России, облегчая, насколько возможно, бедствия народа и войска.
Он, тот медлитель Кутузов, которого девиз есть терпение и время, враг решительных действий, он дает Бородинское сражение, облекая приготовления к нему в беспримерную торжественность. Он, тот Кутузов, который в Аустерлицком сражении, прежде начала его, говорит, что оно будет проиграно, в Бородине, несмотря на уверения генералов о том, что сражение проиграно, несмотря на неслыханный в истории пример того, что после выигранного сражения войско должно отступать, он один, в противность всем, до самой смерти утверждает, что Бородинское сражение – победа. Он один во все время отступления настаивает на том, чтобы не давать сражений, которые теперь бесполезны, не начинать новой войны и не переходить границ России.
Теперь понять значение события, если только не прилагать к деятельности масс целей, которые были в голове десятка людей, легко, так как все событие с его последствиями лежит перед нами.
Но каким образом тогда этот старый человек, один, в противность мнения всех, мог угадать, так верно угадал тогда значение народного смысла события, что ни разу во всю свою деятельность не изменил ему?
Источник этой необычайной силы прозрения в смысл совершающихся явлений лежал в том народном чувстве, которое он носил в себе во всей чистоте и силе его.
Только признание в нем этого чувства заставило народ такими странными путями из в немилости находящегося старика выбрать его против воли царя в представители народной войны. И только это чувство поставило его на ту высшую человеческую высоту, с которой он, главнокомандующий, направлял все свои силы не на то, чтоб убивать и истреблять людей, а на то, чтобы спасать и жалеть их.
Простая, скромная и потому истинно величественная фигура эта не могла улечься в ту лживую форму европейского героя, мнимо управляющего людьми, которую придумала история.
Для лакея не может быть великого человека, потому что у лакея свое понятие о величии.


5 ноября был первый день так называемого Красненского сражения. Перед вечером, когда уже после многих споров и ошибок генералов, зашедших не туда, куда надо; после рассылок адъютантов с противуприказаниями, когда уже стало ясно, что неприятель везде бежит и сражения не может быть и не будет, Кутузов выехал из Красного и поехал в Доброе, куда была переведена в нынешний день главная квартира.
День был ясный, морозный. Кутузов с огромной свитой недовольных им, шушукающихся за ним генералов, верхом на своей жирной белой лошадке ехал к Доброму. По всей дороге толпились, отогреваясь у костров, партии взятых нынешний день французских пленных (их взято было в этот день семь тысяч). Недалеко от Доброго огромная толпа оборванных, обвязанных и укутанных чем попало пленных гудела говором, стоя на дороге подле длинного ряда отпряженных французских орудий. При приближении главнокомандующего говор замолк, и все глаза уставились на Кутузова, который в своей белой с красным околышем шапке и ватной шинели, горбом сидевшей на его сутуловатых плечах, медленно подвигался по дороге. Один из генералов докладывал Кутузову, где взяты орудия и пленные.
Кутузов, казалось, чем то озабочен и не слышал слов генерала. Он недовольно щурился и внимательно и пристально вглядывался в те фигуры пленных, которые представляли особенно жалкий вид. Большая часть лиц французских солдат были изуродованы отмороженными носами и щеками, и почти у всех были красные, распухшие и гноившиеся глаза.
Одна кучка французов стояла близко у дороги, и два солдата – лицо одного из них было покрыто болячками – разрывали руками кусок сырого мяса. Что то было страшное и животное в том беглом взгляде, который они бросили на проезжавших, и в том злобном выражении, с которым солдат с болячками, взглянув на Кутузова, тотчас же отвернулся и продолжал свое дело.
Кутузов долго внимательно поглядел на этих двух солдат; еще более сморщившись, он прищурил глаза и раздумчиво покачал головой. В другом месте он заметил русского солдата, который, смеясь и трепля по плечу француза, что то ласково говорил ему. Кутузов опять с тем же выражением покачал головой.
– Что ты говоришь? Что? – спросил он у генерала, продолжавшего докладывать и обращавшего внимание главнокомандующего на французские взятые знамена, стоявшие перед фронтом Преображенского полка.
– А, знамена! – сказал Кутузов, видимо с трудом отрываясь от предмета, занимавшего его мысли. Он рассеянно оглянулся. Тысячи глаз со всех сторон, ожидая его сло ва, смотрели на него.
Перед Преображенским полком он остановился, тяжело вздохнул и закрыл глаза. Кто то из свиты махнул, чтобы державшие знамена солдаты подошли и поставили их древками знамен вокруг главнокомандующего. Кутузов помолчал несколько секунд и, видимо неохотно, подчиняясь необходимости своего положения, поднял голову и начал говорить. Толпы офицеров окружили его. Он внимательным взглядом обвел кружок офицеров, узнав некоторых из них.
– Благодарю всех! – сказал он, обращаясь к солдатам и опять к офицерам. В тишине, воцарившейся вокруг него, отчетливо слышны были его медленно выговариваемые слова. – Благодарю всех за трудную и верную службу. Победа совершенная, и Россия не забудет вас. Вам слава вовеки! – Он помолчал, оглядываясь.
– Нагни, нагни ему голову то, – сказал он солдату, державшему французского орла и нечаянно опустившему его перед знаменем преображенцев. – Пониже, пониже, так то вот. Ура! ребята, – быстрым движением подбородка обратись к солдатам, проговорил он.
– Ура ра ра! – заревели тысячи голосов. Пока кричали солдаты, Кутузов, согнувшись на седле, склонил голову, и глаз его засветился кротким, как будто насмешливым, блеском.
– Вот что, братцы, – сказал он, когда замолкли голоса…
И вдруг голос и выражение лица его изменились: перестал говорить главнокомандующий, а заговорил простой, старый человек, очевидно что то самое нужное желавший сообщить теперь своим товарищам.
В толпе офицеров и в рядах солдат произошло движение, чтобы яснее слышать то, что он скажет теперь.
– А вот что, братцы. Я знаю, трудно вам, да что же делать! Потерпите; недолго осталось. Выпроводим гостей, отдохнем тогда. За службу вашу вас царь не забудет. Вам трудно, да все же вы дома; а они – видите, до чего они дошли, – сказал он, указывая на пленных. – Хуже нищих последних. Пока они были сильны, мы себя не жалели, а теперь их и пожалеть можно. Тоже и они люди. Так, ребята?
Он смотрел вокруг себя, и в упорных, почтительно недоумевающих, устремленных на него взглядах он читал сочувствие своим словам: лицо его становилось все светлее и светлее от старческой кроткой улыбки, звездами морщившейся в углах губ и глаз. Он помолчал и как бы в недоумении опустил голову.
– А и то сказать, кто же их к нам звал? Поделом им, м… и… в г…. – вдруг сказал он, подняв голову. И, взмахнув нагайкой, он галопом, в первый раз во всю кампанию, поехал прочь от радостно хохотавших и ревевших ура, расстроивавших ряды солдат.
Слова, сказанные Кутузовым, едва ли были поняты войсками. Никто не сумел бы передать содержания сначала торжественной и под конец простодушно стариковской речи фельдмаршала; но сердечный смысл этой речи не только был понят, но то самое, то самое чувство величественного торжества в соединении с жалостью к врагам и сознанием своей правоты, выраженное этим, именно этим стариковским, добродушным ругательством, – это самое (чувство лежало в душе каждого солдата и выразилось радостным, долго не умолкавшим криком. Когда после этого один из генералов с вопросом о том, не прикажет ли главнокомандующий приехать коляске, обратился к нему, Кутузов, отвечая, неожиданно всхлипнул, видимо находясь в сильном волнении.


8 го ноября последний день Красненских сражений; уже смерклось, когда войска пришли на место ночлега. Весь день был тихий, морозный, с падающим легким, редким снегом; к вечеру стало выясняться. Сквозь снежинки виднелось черно лиловое звездное небо, и мороз стал усиливаться.
Мушкатерский полк, вышедший из Тарутина в числе трех тысяч, теперь, в числе девятисот человек, пришел одним из первых на назначенное место ночлега, в деревне на большой дороге. Квартиргеры, встретившие полк, объявили, что все избы заняты больными и мертвыми французами, кавалеристами и штабами. Была только одна изба для полкового командира.
Полковой командир подъехал к своей избе. Полк прошел деревню и у крайних изб на дороге поставил ружья в козлы.
Как огромное, многочленное животное, полк принялся за работу устройства своего логовища и пищи. Одна часть солдат разбрелась, по колено в снегу, в березовый лес, бывший вправо от деревни, и тотчас же послышались в лесу стук топоров, тесаков, треск ломающихся сучьев и веселые голоса; другая часть возилась около центра полковых повозок и лошадей, поставленных в кучку, доставая котлы, сухари и задавая корм лошадям; третья часть рассыпалась в деревне, устраивая помещения штабным, выбирая мертвые тела французов, лежавшие по избам, и растаскивая доски, сухие дрова и солому с крыш для костров и плетни для защиты.
Человек пятнадцать солдат за избами, с края деревни, с веселым криком раскачивали высокий плетень сарая, с которого снята уже была крыша.
– Ну, ну, разом, налегни! – кричали голоса, и в темноте ночи раскачивалось с морозным треском огромное, запорошенное снегом полотно плетня. Чаще и чаще трещали нижние колья, и, наконец, плетень завалился вместе с солдатами, напиравшими на него. Послышался громкий грубо радостный крик и хохот.
– Берись по двое! рочаг подавай сюда! вот так то. Куда лезешь то?
– Ну, разом… Да стой, ребята!.. С накрика!
Все замолкли, и негромкий, бархатно приятный голос запел песню. В конце третьей строфы, враз с окончанием последнего звука, двадцать голосов дружно вскрикнули: «Уууу! Идет! Разом! Навались, детки!..» Но, несмотря на дружные усилия, плетень мало тронулся, и в установившемся молчании слышалось тяжелое пыхтенье.
– Эй вы, шестой роты! Черти, дьяволы! Подсоби… тоже мы пригодимся.
Шестой роты человек двадцать, шедшие в деревню, присоединились к тащившим; и плетень, саженей в пять длины и в сажень ширины, изогнувшись, надавя и режа плечи пыхтевших солдат, двинулся вперед по улице деревни.
– Иди, что ли… Падай, эка… Чего стал? То то… Веселые, безобразные ругательства не замолкали.
– Вы чего? – вдруг послышался начальственный голос солдата, набежавшего на несущих.
– Господа тут; в избе сам анарал, а вы, черти, дьяволы, матершинники. Я вас! – крикнул фельдфебель и с размаху ударил в спину первого подвернувшегося солдата. – Разве тихо нельзя?