HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-21
1 <p><a>#статьи</a></p>
1 <p><a>#статьи</a></p>
2 <ul><li>13 ноя 2023</li>
2 <ul><li>13 ноя 2023</li>
3 <li>0</li>
3 <li>0</li>
4 </ul><h2>Что такое компилятор и как он работает</h2>
4 </ul><h2>Что такое компилятор и как он работает</h2>
5 <p>Знакомимся с программой, которая умеет создавать другие программы для того, чтобы создавать ещё больше программ.</p>
5 <p>Знакомимся с программой, которая умеет создавать другие программы для того, чтобы создавать ещё больше программ.</p>
6 <p>Иллюстрация: Оля Ежак для Skillbox Media</p>
6 <p>Иллюстрация: Оля Ежак для Skillbox Media</p>
7 <p>Любитель научной фантастики и технологического прогресса. Хорошо сочетает в себе заумного технаря и утончённого гуманитария. Пишет про IT и радуется этому.</p>
7 <p>Любитель научной фантастики и технологического прогресса. Хорошо сочетает в себе заумного технаря и утончённого гуманитария. Пишет про IT и радуется этому.</p>
8 <p><strong>Компилятор</strong> - это программа, которая переводит исходный код на языке программирования в машинный код. Если этого не сделать, компьютер не поймёт, как выполнить инструкции разработчика. Поэтому мы отдаём компилятору строки кода, а он сравнивает их со своим словарём, учитывает контекст и выдаёт набор из нулей и единиц.</p>
8 <p><strong>Компилятор</strong> - это программа, которая переводит исходный код на языке программирования в машинный код. Если этого не сделать, компьютер не поймёт, как выполнить инструкции разработчика. Поэтому мы отдаём компилятору строки кода, а он сравнивает их со своим словарём, учитывает контекст и выдаёт набор из нулей и единиц.</p>
9 <p>В этой статье разберёмся:</p>
9 <p>В этой статье разберёмся:</p>
10 <ul><li><a>для чего нужны компиляторы</a>;</li>
10 <ul><li><a>для чего нужны компиляторы</a>;</li>
11 <li><a>как они работают</a>;</li>
11 <li><a>как они работают</a>;</li>
12 <li><a>на каких языках их пишут</a>;</li>
12 <li><a>на каких языках их пишут</a>;</li>
13 <li><a>почему у одного языка может быть несколько компиляторов</a>;</li>
13 <li><a>почему у одного языка может быть несколько компиляторов</a>;</li>
14 <li><a>какие они бывают</a>;</li>
14 <li><a>какие они бывают</a>;</li>
15 <li><a>в чём их отличие от интерпретаторов и трансляторов</a>;</li>
15 <li><a>в чём их отличие от интерпретаторов и трансляторов</a>;</li>
16 <li><a>какие плюсы и минусы есть у компилируемых языков</a>;</li>
16 <li><a>какие плюсы и минусы есть у компилируемых языков</a>;</li>
17 <li><a>где узнать про компиляторы подробнее</a>.</li>
17 <li><a>где узнать про компиляторы подробнее</a>.</li>
18 </ul><p>Выдвинем дерзкое утверждение: компьютеры очень глупы, они не понимают человеческого языка - и, в частности, языков программирования. Всё, что они умеют, - это принимать электрические сигналы и как-то на них реагировать.</p>
18 </ul><p>Выдвинем дерзкое утверждение: компьютеры очень глупы, они не понимают человеческого языка - и, в частности, языков программирования. Всё, что они умеют, - это принимать электрические сигналы и как-то на них реагировать.</p>
19 <p>Если упрощать, то компьютер - это коробка с миллиардами переключателей. Дёрнули одни - сложили два числа, дёрнули другие - записали данные на жёсткий диск. И хотя современные компьютеры с аппаратной точки зрения устроены сложнее, принцип остаётся похожим.</p>
19 <p>Если упрощать, то компьютер - это коробка с миллиардами переключателей. Дёрнули одни - сложили два числа, дёрнули другие - записали данные на жёсткий диск. И хотя современные компьютеры с аппаратной точки зрения устроены сложнее, принцип остаётся похожим.</p>
20 <p>Когда мы пишем код, то используем понятные для людей слова, такие как print, string, import, Процедура и Исключение. Нам их значение кажется очевидным: здесь вывели результат на печать, а там объявили строковую переменную. Но для компьютера эти слова ничего не значат.</p>
20 <p>Когда мы пишем код, то используем понятные для людей слова, такие как print, string, import, Процедура и Исключение. Нам их значение кажется очевидным: здесь вывели результат на печать, а там объявили строковую переменную. Но для компьютера эти слова ничего не значат.</p>
21 <p>Компьютер видит слово<em>print</em>и воспринимает его ровно так же, как вы воспринимаете слова из любого неизвестного вам языка. Ничего не понятно, но какой-то смысл у них точно есть. Поэтому компьютеру, как и нам, нужен переводчик - или компилятор.</p>
21 <p>Компьютер видит слово<em>print</em>и воспринимает его ровно так же, как вы воспринимаете слова из любого неизвестного вам языка. Ничего не понятно, но какой-то смысл у них точно есть. Поэтому компьютеру, как и нам, нужен переводчик - или компилятор.</p>
22 <p>Компилятор понимает, что значит слово print - и даже умеет сказать компьютеру, как его правильно обработать. Таким образом, он решает три задачи:</p>
22 <p>Компилятор понимает, что значит слово print - и даже умеет сказать компьютеру, как его правильно обработать. Таким образом, он решает три задачи:</p>
23 <ul><li>разбирает синтаксис написанного;</li>
23 <ul><li>разбирает синтаксис написанного;</li>
24 <li>анализирует его;</li>
24 <li>анализирует его;</li>
25 <li>генерирует машинный код.</li>
25 <li>генерирует машинный код.</li>
26 </ul><p>На вход компилятор принимает исходный код, а отдаёт исполняемый файл - программу, которая готова к работе.</p>
26 </ul><p>На вход компилятор принимает исходный код, а отдаёт исполняемый файл - программу, которая готова к работе.</p>
27 <p>Звучит просто. Но к компиляторам есть много вопросов - например, на каких языках их пишут, как они устроены внутри и каких видов бывают. Обо всём этом расскажем в статье. И начнём с того, как работают компиляторы.</p>
27 <p>Звучит просто. Но к компиляторам есть много вопросов - например, на каких языках их пишут, как они устроены внутри и каких видов бывают. Обо всём этом расскажем в статье. И начнём с того, как работают компиляторы.</p>
28 <p>Итак, ещё раз: чтобы компьютеры выполняли команды программистов, им нужны переводчики с человеческого на машинный. Рассмотрим процесс перевода - сначала в общих чертах, а потом подробно.</p>
28 <p>Итак, ещё раз: чтобы компьютеры выполняли команды программистов, им нужны переводчики с человеческого на машинный. Рассмотрим процесс перевода - сначала в общих чертах, а потом подробно.</p>
29 <p><strong>?‍♂️</strong><strong>Коротко</strong></p>
29 <p><strong>?‍♂️</strong><strong>Коротко</strong></p>
30 <p>Компилятор получает на вход файл с кодом на каком-то языке программирования. Он преобразовывает конструкции языка в формат, понятный компьютеру, и возвращает файл, который тот сможет выполнить.</p>
30 <p>Компилятор получает на вход файл с кодом на каком-то языке программирования. Он преобразовывает конструкции языка в формат, понятный компьютеру, и возвращает файл, который тот сможет выполнить.</p>
31 <p>Чтобы преобразовать исходный код, компилятор использует собственный словарь с определениями - например, оператор if меняет на 11010011100110, а сложение - на <em>101011</em>. Он делает это, пока не закончатся все строки в файле. Получается исполнительный файл, который выглядит так:</p>
31 <p>Чтобы преобразовать исходный код, компилятор использует собственный словарь с определениями - например, оператор if меняет на 11010011100110, а сложение - на <em>101011</em>. Он делает это, пока не закончатся все строки в файле. Получается исполнительный файл, который выглядит так:</p>
32 <p>001011011010010101110101010101010100001100001110111100110100001010001001110…</p>
32 <p>001011011010010101110101010101010100001100001110111100110100001010001001110…</p>
33 <p>В таком формате компьютеру уже удобно читать инструкции и выполнять их. А значит, компилятор сделал свою работу хорошо.</p>
33 <p>В таком формате компьютеру уже удобно читать инструкции и выполнять их. А значит, компилятор сделал свою работу хорошо.</p>
34 <p><strong>?</strong><strong>Подробнее.</strong>Компилирование состоит из пяти этапов: синтаксического анализа, парсинга, семантического анализа, оптимизации и генерации кода. Давайте разберём каждую стадию.</p>
34 <p><strong>?</strong><strong>Подробнее.</strong>Компилирование состоит из пяти этапов: синтаксического анализа, парсинга, семантического анализа, оптимизации и генерации кода. Давайте разберём каждую стадию.</p>
35 <p>1️⃣<strong>Синтаксический анализ.</strong>Это что-то вроде разбора грамматики языка. Когда мы пишем код, то следуем определённым правилам - синтаксису. Например, в Java между командами ставим точку с запятой. Если этого не сделать, то получим ошибку.</p>
35 <p>1️⃣<strong>Синтаксический анализ.</strong>Это что-то вроде разбора грамматики языка. Когда мы пишем код, то следуем определённым правилам - синтаксису. Например, в Java между командами ставим точку с запятой. Если этого не сделать, то получим ошибку.</p>
36 <p>На этапе синтаксического анализа компилятор проверяет, соответствует ли код правилам конкретного языка программирования. И пока он не думает о том, что именно написано, - проверка идёт только по формальным признакам.</p>
36 <p>На этапе синтаксического анализа компилятор проверяет, соответствует ли код правилам конкретного языка программирования. И пока он не думает о том, что именно написано, - проверка идёт только по формальным признакам.</p>
37 <p>2️⃣<strong>Парсинг.</strong>На этом этапе компилятор разбивает код на маленькие кусочки - токены. Каждый токен - это какое-то слово или символ, например if, while, int или (.</p>
37 <p>2️⃣<strong>Парсинг.</strong>На этом этапе компилятор разбивает код на маленькие кусочки - токены. Каждый токен - это какое-то слово или символ, например if, while, int или (.</p>
38 <p>Из токенов строится синтаксическое дерево, которое содержит слова и символы, и пригодится на следующем этапе - семантическом анализе. Каждый узел дерева - это либо операция, например сложение, либо переменная. Обычно, когда мы доходим до переменной, то дальше ветви не разрастаются.</p>
38 <p>Из токенов строится синтаксическое дерево, которое содержит слова и символы, и пригодится на следующем этапе - семантическом анализе. Каждый узел дерева - это либо операция, например сложение, либо переменная. Обычно, когда мы доходим до переменной, то дальше ветви не разрастаются.</p>
39 <p>Давайте посмотрим, как выглядит такое дерево.</p>
39 <p>Давайте посмотрим, как выглядит такое дерево.</p>
40 <p>Допустим, у нас есть простой код со сложением двух чисел:</p>
40 <p>Допустим, у нас есть простой код со сложением двух чисел:</p>
41 <p>x = 5 + 3</p>
41 <p>x = 5 + 3</p>
42 <p>Здесь пять токенов: x, =, 5, + и 3. Пробелы считать не будем. Из этих токенов строится такое дерево:</p>
42 <p>Здесь пять токенов: x, =, 5, + и 3. Пробелы считать не будем. Из этих токенов строится такое дерево:</p>
43 Обычно синтаксические деревья намного сложнее - очень намного.<em>Изображение: Skillbox Media</em><p>Мы видим, что на вершине находится главная операция - присваивание переменной x результата сложения двух чисел. От неё отходит две ветви - сама переменная x и символ сложения, который ветвится на слагаемые числа.</p>
43 Обычно синтаксические деревья намного сложнее - очень намного.<em>Изображение: Skillbox Media</em><p>Мы видим, что на вершине находится главная операция - присваивание переменной x результата сложения двух чисел. От неё отходит две ветви - сама переменная x и символ сложения, который ветвится на слагаемые числа.</p>
44 <p>В процессе парсинга компилятор не понимает, зачем нужен каждый из токенов. Пока что он машинально выполняет свою работу - думать будет на следующем этапе.</p>
44 <p>В процессе парсинга компилятор не понимает, зачем нужен каждый из токенов. Пока что он машинально выполняет свою работу - думать будет на следующем этапе.</p>
45 <p>3️⃣<strong>Семантический анализ.</strong>Компилятор начинает вдумываться в то, что написано в коде, анализируя составленное синтаксическое дерево. Например, если мы объявили переменную, он понимает, что это значит и какие операции можно с ней выполнить.</p>
45 <p>3️⃣<strong>Семантический анализ.</strong>Компилятор начинает вдумываться в то, что написано в коде, анализируя составленное синтаксическое дерево. Например, если мы объявили переменную, он понимает, что это значит и какие операции можно с ней выполнить.</p>
46 <p>Ещё компилятор на этом этапе может предполагать, какие именно действия с переменной возможны. Если он видит, что у нас есть переменная неизменяемого типа, например константа, то при попытке кода её изменить, выдаст ошибку.</p>
46 <p>Ещё компилятор на этом этапе может предполагать, какие именно действия с переменной возможны. Если он видит, что у нас есть переменная неизменяемого типа, например константа, то при попытке кода её изменить, выдаст ошибку.</p>
47 <p>4️⃣<strong>Оптимизация.</strong>Когда синтаксис разобран и стало понятно, что делает программа, время ускорить работу кода. Компилятор ищет способы повысить скорость его выполнения или уменьшить количество занимаемой им памяти.</p>
47 <p>4️⃣<strong>Оптимизация.</strong>Когда синтаксис разобран и стало понятно, что делает программа, время ускорить работу кода. Компилятор ищет способы повысить скорость его выполнения или уменьшить количество занимаемой им памяти.</p>
48 <p>Самый простой пример оптимизации - умножение на ноль. Например, у нас есть фрагмент кода:</p>
48 <p>Самый простой пример оптимизации - умножение на ноль. Например, у нас есть фрагмент кода:</p>
49 int x = sin(126) * cos(54) + tan(78); int y = x * 0;<p>Чтобы определить значение переменной y, потребуется сначала вычислить сложную формулу для переменной x. Но мы, люди, сразу видим, что при умножении на ноль, результат будет нулём, а значит, смысла считать переменную x нет. Компилятор тоже видит такие вещи - и не будет вычислять то, что вычислять бесполезно. Он просто заменит эти две строки кода на одну:</p>
49 int x = sin(126) * cos(54) + tan(78); int y = x * 0;<p>Чтобы определить значение переменной y, потребуется сначала вычислить сложную формулу для переменной x. Но мы, люди, сразу видим, что при умножении на ноль, результат будет нулём, а значит, смысла считать переменную x нет. Компилятор тоже видит такие вещи - и не будет вычислять то, что вычислять бесполезно. Он просто заменит эти две строки кода на одну:</p>
50 int y = 0;<p>Удобно, правда? Но это сработает только в том случае, если переменная x не пригодится нам в программе дальше.</p>
50 int y = 0;<p>Удобно, правда? Но это сработает только в том случае, если переменная x не пригодится нам в программе дальше.</p>
51 <p>Это возможно из-за особенностей работы компилятора - он не выполняет код, а сначала читает его и ищет способы оптимизации программы.</p>
51 <p>Это возможно из-за особенностей работы компилятора - он не выполняет код, а сначала читает его и ищет способы оптимизации программы.</p>
52 <p>5️⃣<strong>Генерация кода.</strong>Синтаксис разобран, анализ проведён, код оптимизирован - пора перевести его на язык компьютера. На этом этапе все команды, что мы писали на языке программирования, переводятся в машинные инструкции.</p>
52 <p>5️⃣<strong>Генерация кода.</strong>Синтаксис разобран, анализ проведён, код оптимизирован - пора перевести его на язык компьютера. На этом этапе все команды, что мы писали на языке программирования, переводятся в машинные инструкции.</p>
53 <p>После перевода мы получаем исполняемый файл, например в формате .exe, который можно запустить и проверить работу программы. На этом компиляция завершается.</p>
53 <p>После перевода мы получаем исполняемый файл, например в формате .exe, который можно запустить и проверить работу программы. На этом компиляция завершается.</p>
54 <p><em>? Подождите, раз компилятор переводит исходный код в машинный, а сам он является программой, то на каком языке тогда он написан? Какой-то замкнутый круг получается.</em></p>
54 <p><em>? Подождите, раз компилятор переводит исходный код в машинный, а сам он является программой, то на каком языке тогда он написан? Какой-то замкнутый круг получается.</em></p>
55 <p>На самом деле всё не так сложно. Компиляторы можно писать на любом языке - хоть на Python, хоть на языке ассемблера. Но есть нюанс.</p>
55 <p>На самом деле всё не так сложно. Компиляторы можно писать на любом языке - хоть на Python, хоть на языке ассемблера. Но есть нюанс.</p>
56 <p>Самый первый компилятор написан на языке ассемблера, потому что программистам нужно было как-то упростить себе работу с машинным кодом. Работают они так:</p>
56 <p>Самый первый компилятор написан на языке ассемблера, потому что программистам нужно было как-то упростить себе работу с машинным кодом. Работают они так:</p>
57 <ul><li>разработчик пишет код на ассемблере;</li>
57 <ul><li>разработчик пишет код на ассемблере;</li>
58 <li>компилятор переводит его в машинные инструкции;</li>
58 <li>компилятор переводит его в машинные инструкции;</li>
59 <li>компьютер запускает эти инструкции.</li>
59 <li>компьютер запускает эти инструкции.</li>
60 </ul><p>Получается, что компилятор на ассемблере - это другая программа на нём же, которая умеет переводить код. Например, она подставляет вместо команды jmp строку 001110111, которая запускает нужные шестерёнки внутри процессора.</p>
60 </ul><p>Получается, что компилятор на ассемблере - это другая программа на нём же, которая умеет переводить код. Например, она подставляет вместо команды jmp строку 001110111, которая запускает нужные шестерёнки внутри процессора.</p>
61 <p>После уже появились языки более высокого уровня - например, C. Компилятор для C написан на том же ассемблере. Работает он похожим образом:</p>
61 <p>После уже появились языки более высокого уровня - например, C. Компилятор для C написан на том же ассемблере. Работает он похожим образом:</p>
62 <ul><li>разработчик пишет программу на C;</li>
62 <ul><li>разработчик пишет программу на C;</li>
63 <li>компилятор переводит команды на языке программирования с C в машинные инструкции;</li>
63 <li>компилятор переводит команды на языке программирования с C в машинные инструкции;</li>
64 <li>компьютер запускает эти инструкции.</li>
64 <li>компьютер запускает эти инструкции.</li>
65 </ul><p>Дальше - вверх по высокоуровневости языков программирования. Компилятор на С++ написан на C, а для JavaScript - на C++. Но если спускаться по цепочке, то мы рано или поздно придём к ассемблеру.</p>
65 </ul><p>Дальше - вверх по высокоуровневости языков программирования. Компилятор на С++ написан на C, а для JavaScript - на C++. Но если спускаться по цепочке, то мы рано или поздно придём к ассемблеру.</p>
66 <p><em>? Стойте, а зачем тогда языкам программирования несколько компиляторов? Почему бы всем не использовать только один?</em></p>
66 <p><em>? Стойте, а зачем тогда языкам программирования несколько компиляторов? Почему бы всем не использовать только один?</em></p>
67 <p>Для каждого языка программирования первый компилятор обычно пишут его разработчики. Например, возьмём язык C.</p>
67 <p>Для каждого языка программирования первый компилятор обычно пишут его разработчики. Например, возьмём язык C.</p>
68 <p>Его компилятор написан на ассемблере, а сделал это<a>Деннис Ритчи</a>. Он исходил из принципов, что одни команды языка должны конвертироваться в одни инструкции для ассемблера, а другие - в другие. Но, возможно, это была не лучшая реализация: в каких-то местах компилятор мог работать медленно, а в каких-то и вовсе не справлялся. Поэтому сторонние разработчики решили написать свои версии "переводчика" кода на C.</p>
68 <p>Его компилятор написан на ассемблере, а сделал это<a>Деннис Ритчи</a>. Он исходил из принципов, что одни команды языка должны конвертироваться в одни инструкции для ассемблера, а другие - в другие. Но, возможно, это была не лучшая реализация: в каких-то местах компилятор мог работать медленно, а в каких-то и вовсе не справлялся. Поэтому сторонние разработчики решили написать свои версии "переводчика" кода на C.</p>
69 <p>Например, кто-то мог взглянуть на код компилятора C и подумать: "Да тут же нет<a>сборщика мусора</a>, это что такое-то?!" - и пойти написать свою версию, которая будет залатывать все утечки памяти и чистить неиспользуемые переменные.</p>
69 <p>Например, кто-то мог взглянуть на код компилятора C и подумать: "Да тут же нет<a>сборщика мусора</a>, это что такое-то?!" - и пойти написать свою версию, которая будет залатывать все утечки памяти и чистить неиспользуемые переменные.</p>
70 <p>Другой разработчик может взглянуть и подумать: да тут же нет нормальной оптимизации под мои задачи из машинного обучения. А затем пойти и написать компилятор, который будет конвертировать код на C в TensorFlow-структуры.</p>
70 <p>Другой разработчик может взглянуть и подумать: да тут же нет нормальной оптимизации под мои задачи из машинного обучения. А затем пойти и написать компилятор, который будет конвертировать код на C в TensorFlow-структуры.</p>
71 <p>Каждая реализация компилятора нужна для своих целей: кому-то важно собирать мусор, а кому-то иметь супербыстрый код, который обгонит любой другой. Это значит, что они будут различаться архитектурой, используемым языком программирования, скоростью работы и назначением. Но глобально - будут делать одну и ту же вещь: компилировать.</p>
71 <p>Каждая реализация компилятора нужна для своих целей: кому-то важно собирать мусор, а кому-то иметь супербыстрый код, который обгонит любой другой. Это значит, что они будут различаться архитектурой, используемым языком программирования, скоростью работы и назначением. Но глобально - будут делать одну и ту же вещь: компилировать.</p>
72 <p>К сожалению, ещё нет универсального компилятора, который бы переводил код любого языка программирования в машинный код для всех устройств. У нас есть разные операционные системы, их версии, разная архитектура процессоров и так далее.</p>
72 <p>К сожалению, ещё нет универсального компилятора, который бы переводил код любого языка программирования в машинный код для всех устройств. У нас есть разные операционные системы, их версии, разная архитектура процессоров и так далее.</p>
73 <p>В зависимости от задач компиляторы можно разделить на несколько групп. Например, по направлению перевода кода.</p>
73 <p>В зависимости от задач компиляторы можно разделить на несколько групп. Например, по направлению перевода кода.</p>
74 <p>Умеют переводить код на языке программирования в машинный. Именно о них мы преимущественно и говорили в этой статье. Пример -<a>компилятор g++</a>для языка C++.</p>
74 <p>Умеют переводить код на языке программирования в машинный. Именно о них мы преимущественно и говорили в этой статье. Пример -<a>компилятор g++</a>для языка C++.</p>
75 <p>Эти компиляторы работают на одной платформе и создают код для другой. Их часто используют разработчики для встроенных систем, мощности которых недостаточно для самостоятельного компилирования. Например, в микроконтроллерах.</p>
75 <p>Эти компиляторы работают на одной платформе и создают код для другой. Их часто используют разработчики для встроенных систем, мощности которых недостаточно для самостоятельного компилирования. Например, в микроконтроллерах.</p>
76 <p>К кросс-компиляторам относят<a>GCC</a>(GNU Compiler Collection). Он поддерживает C++, Objective-C, Java, Fortran и Go и разную архитектуру процессоров.</p>
76 <p>К кросс-компиляторам относят<a>GCC</a>(GNU Compiler Collection). Он поддерживает C++, Objective-C, Java, Fortran и Go и разную архитектуру процессоров.</p>
77 <em>Кадр: сериал "Кремниевая долина" / HBO</em><p>Преобразуют исходный код языка высокого уровня в исходный код другого языка высокого уровня. Например, транспайлер<a>Babel</a>преобразует ECMAScript 2015+ в JavaScript.</p>
77 <em>Кадр: сериал "Кремниевая долина" / HBO</em><p>Преобразуют исходный код языка высокого уровня в исходный код другого языка высокого уровня. Например, транспайлер<a>Babel</a>преобразует ECMAScript 2015+ в JavaScript.</p>
78 <p>Эти компиляторы делают обратное действие - анализируют уже скомпилированный код и пытаются превратить его в исходный код на высокоуровневом языке. Это может быть полезно для анализа или отладки.</p>
78 <p>Эти компиляторы делают обратное действие - анализируют уже скомпилированный код и пытаются превратить его в исходный код на высокоуровневом языке. Это может быть полезно для анализа или отладки.</p>
79 <p>Компиляторы - это не единственный способ перевести исходный код в машинный. Ещё есть интерпретаторы и JIT-компиляторы. Давайте коротко расскажем, в чём различия между ними.</p>
79 <p>Компиляторы - это не единственный способ перевести исходный код в машинный. Ещё есть интерпретаторы и JIT-компиляторы. Давайте коротко расскажем, в чём различия между ними.</p>
80 <p><strong>Интерпретатор.</strong>Это как синхронный переводчик. Он читает исходный код и сразу же выполняет его построчно. Интерпретатор не создаёт дополнительных файлов и не строит синтаксические деревья, а выполняет инструкции на лету, переводя их в байт-код. Например, так работает<a>CPython</a>для языка Python.</p>
80 <p><strong>Интерпретатор.</strong>Это как синхронный переводчик. Он читает исходный код и сразу же выполняет его построчно. Интерпретатор не создаёт дополнительных файлов и не строит синтаксические деревья, а выполняет инструкции на лету, переводя их в байт-код. Например, так работает<a>CPython</a>для языка Python.</p>
81 <p><strong>JIT-компилятор.</strong>Это гибрид компилятора и интерпретатора. Он начинает работать как интерпретатор и выполняет команды по ходу чтения кода. Но часть команд переводит в машинный код, чтобы использовать их в тех случаях, если они будут повторяться в будущем. Это ускоряет работу программы, так как позволяет не выполнять одно и то же действие повторно.</p>
81 <p><strong>JIT-компилятор.</strong>Это гибрид компилятора и интерпретатора. Он начинает работать как интерпретатор и выполняет команды по ходу чтения кода. Но часть команд переводит в машинный код, чтобы использовать их в тех случаях, если они будут повторяться в будущем. Это ускоряет работу программы, так как позволяет не выполнять одно и то же действие повторно.</p>
82 <p>Отдельно стоит упомянуть<strong>байт-код</strong>. Это специальный код, который запускается на виртуальной машине. Можно сказать, что он занимает промежуточное положение между кодом, написанным на языке программирования, и машинным кодом. Его реализацию можно найти в Java или Python.</p>
82 <p>Отдельно стоит упомянуть<strong>байт-код</strong>. Это специальный код, который запускается на виртуальной машине. Можно сказать, что он занимает промежуточное положение между кодом, написанным на языке программирования, и машинным кодом. Его реализацию можно найти в Java или Python.</p>
83 <p>Давайте посмотрим на список аргументов за и против для компилируемых языков - то есть тех, которые используют компиляторы. Примеры таких языков: C++, Haskell, Fortran, Rust, Swift и Go.</p>
83 <p>Давайте посмотрим на список аргументов за и против для компилируемых языков - то есть тех, которые используют компиляторы. Примеры таких языков: C++, Haskell, Fortran, Rust, Swift и Go.</p>
84 <p>✅<strong>Быстрота выполнения.</strong>Компилятор переводит исходный код в машинный всего один раз. А дальше - всё уже оптимизировано и готово к запуску. Поэтому такие программы работают быстрее, так как компьютеру не приходится тратить время на их повторный перевод.</p>
84 <p>✅<strong>Быстрота выполнения.</strong>Компилятор переводит исходный код в машинный всего один раз. А дальше - всё уже оптимизировано и готово к запуску. Поэтому такие программы работают быстрее, так как компьютеру не приходится тратить время на их повторный перевод.</p>
85 <p>✅<strong>Эффективное использование ресурсов.</strong>Один из этапов компилирования - это оптимизация кода. А так как компиляторы пишут либо создатели языка, либо опытные разработчики, то производительность таких программ будет высокой.</p>
85 <p>✅<strong>Эффективное использование ресурсов.</strong>Один из этапов компилирования - это оптимизация кода. А так как компиляторы пишут либо создатели языка, либо опытные разработчики, то производительность таких программ будет высокой.</p>
86 <p>✅<strong>Скрытие исходного кода.</strong>Это неочевидный плюс, но это правда преимущество. После того как программа скомпилирована, её исходный код понять трудно. Это помогает избежать взломов и обезопасить данные.</p>
86 <p>✅<strong>Скрытие исходного кода.</strong>Это неочевидный плюс, но это правда преимущество. После того как программа скомпилирована, её исходный код понять трудно. Это помогает избежать взломов и обезопасить данные.</p>
87 <p>⛔️<strong>Долгая компиляция.</strong>Процесс компиляции может занимать очень много времени. Для небольших проектов это не так страшно, но когда количество строк кода у проекта переваливает за миллион, то лишний раз запускать компиляцию не хочется.</p>
87 <p>⛔️<strong>Долгая компиляция.</strong>Процесс компиляции может занимать очень много времени. Для небольших проектов это не так страшно, но когда количество строк кода у проекта переваливает за миллион, то лишний раз запускать компиляцию не хочется.</p>
88 <p>⛔️<strong>Сложность исправления ошибок.</strong>Обычно ошибки при компилировании выглядят устрашающе из-за запутанного описания проблемы. Просто попробуйте не поставить точку с запятой в файле с C++ и убедитесь, что ничего хуже вы не видели.</p>
88 <p>⛔️<strong>Сложность исправления ошибок.</strong>Обычно ошибки при компилировании выглядят устрашающе из-за запутанного описания проблемы. Просто попробуйте не поставить точку с запятой в файле с C++ и убедитесь, что ничего хуже вы не видели.</p>
89 <p>⛔️<strong>Зависимость от платформы.</strong>Если скомпилировать программу для Windows, то её никак нельзя будет запустить на macOS. Поэтому придётся дополнительно брать другой компилятор и начинать процесс заново - или использовать кросс-компиляторы.</p>
89 <p>⛔️<strong>Зависимость от платформы.</strong>Если скомпилировать программу для Windows, то её никак нельзя будет запустить на macOS. Поэтому придётся дополнительно брать другой компилятор и начинать процесс заново - или использовать кросс-компиляторы.</p>
90 <p>В этой статье мы затронули только базовые принципы работы компиляторов. Если вы хотите лучше разобраться в том, как они работают, или даже написать свою версию переводчика на машинный язык, вот несколько ресурсов, где можно изучить тему глубже:</p>
90 <p>В этой статье мы затронули только базовые принципы работы компиляторов. Если вы хотите лучше разобраться в том, как они работают, или даже написать свою версию переводчика на машинный язык, вот несколько ресурсов, где можно изучить тему глубже:</p>
91 <ul><li><a>Компиляторы: принципы, технологии и инструментарий</a>Альфреда Ахо и Моники Лам.</li>
91 <ul><li><a>Компиляторы: принципы, технологии и инструментарий</a>Альфреда Ахо и Моники Лам.</li>
92 <li>"Конструирование компиляторов", Сергея Свердлова.</li>
92 <li>"Конструирование компиляторов", Сергея Свердлова.</li>
93 <li>Бесплатный курс "<a>Языки программирования и компиляторы</a>" от Computer Science Center.</li>
93 <li>Бесплатный курс "<a>Языки программирования и компиляторы</a>" от Computer Science Center.</li>
94 </ul><a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
94 </ul><a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>