C# частично интерпретируется или действительно компилируется?

Об этом много противоречивой информации. В то время как некоторые говорят, что C# компилируется (так как он компилируется в IL, а затем в нативный код при запуске), другие говорят, что он интерпретируется так, как ему нужно.NET. EN Wiki говорит:

Многие интерпретируемые языки сначала компилируются в некую форму кода виртуальной машины, которая затем либо интерпретируется, либо компилируется во время выполнения в собственный код.

Так что я совсем запутался. Может ли кто-нибудь объяснить это ясно?

15 ответов

Решение

C# компилируется в IL компилятором C#.

Этот IL затем компилируется точно в срок (JIT) по мере необходимости на родном языке ассемблера хост-машины. Можно было бы написать среду выполнения.NET, которая интерпретировала бы вместо этого IL. Даже если бы это было сделано, я бы до сих пор утверждал, что C# - это скомпилированный язык.

Чисто скомпилированный язык имеет некоторые преимущества. Скорость, как правило, и часто рабочий размер набора. Чисто интерпретированный язык имеет некоторые преимущества. Гибкость, не требующая явной стадии компиляции, которая позволяет нам редактировать на месте, и часто более простая переносимость.

В этом случае смешанный язык вписывается в середину.

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

C# также может быть скомпилирован при первом запуске, как это происходит в ASP.NET, что делает его близким к интерпретируемому в этом случае (хотя он все еще компилируется в IL и затем в этом случае подключается). Конечно, в этом случае он обладает практически всеми преимуществами интерпретации (сравните с VBScript или JScript, используемым в классическом ASP), а также многими преимуществами компилируемого.

Строго говоря, ни один язык не является сопряженным, интерпретируемым или скомпилированным как язык. Мы можем использовать NGen C# для собственного кода (хотя, если он делает что-то вроде динамической загрузки сборки, он все равно будет использовать IL и джиттинг). Мы могли бы написать intepretter для C или C++ (несколько человек сделали это). В своем наиболее распространенном случае использования C# компилируется в IL, который затем соединяется, что не совсем классическое определение интерпретируемого или компилируемого.

Слишком много семантики и высказываний, основанных на мнении.

Во-первых: C# не интерпретируемый язык; CLR и JVM считаются "средами исполнения" или "промежуточным ПО", но одно и то же имя относится к таким вещам, как Perl. Это создает много путаницы среди людей, связанных с именами.

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

Java изначально скомпилирована в байт-код, затем прошла через интерпретатор; теперь JVM читает байт-код и как раз вовремя компилирует его в нативный код. CIL делает то же самое: CLR использует своевременную компиляцию в нативный код.

Рассмотрим все комбинации запуска исходного кода, запуска байт-кода, компиляции в нативную компиляцию, выполняемую точно в срок, запуска исходного кода через компилятор для нативного точного выполнения и так далее. Семантика того, является ли язык компилируемым или интерпретируемым, становится бессмысленной.

В качестве примера: многие интерпретируемые языки используют компиляцию байт-кода точно в срок. C# компилируется в CIL, который JIT компилирует в native; напротив, Perl немедленно компилирует скрипт в байт-код, а затем запускает этот байт-код через интерпретатор. Вы можете запустить сборку C# только в формате байт-кода CIL; Вы можете запустить скрипт Perl только в формате исходного кода.

Компиляторы точно вовремя также запускают много внешних и внутренних контрольно-измерительных приборов. Среда выполнения отслеживает выполнение различных функций, а затем корректирует компоновку кода, чтобы оптимизировать ветви и организацию кода для его конкретного потока выполнения. Это означает, что JIT-код может выполняться быстрее, чем собственный скомпилированный код (как, например, C++ или C#, запускаемый через IL2CPP), потому что JIT корректирует свою стратегию оптимизации в соответствии с фактическим случаем выполнения кода при его запуске.

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

Если вы чувствуете, узнали или ушли из старой школы, что скомпилированный EXE идет от исходного кода к машинному коду, тогда интерпретируется C#. Если вы думаете, что скомпилированный означает преобразование исходного кода в другой код, такой как байт-код, то да, он преобразован. Для меня все, что требует обработки во время выполнения для работы в ОС, для которой оно было построено, интерпретируется.

Посмотрите здесь: http://msdn.microsoft.com/library/z1zx9t92

Исходный код, написанный на C#, компилируется в промежуточный язык (IL), который соответствует спецификации CLI.

(...)

Когда программа на C# выполняется, сборка загружается в CLR, которая может выполнять различные действия на основе информации в манифесте. Затем, если требования безопасности соблюдены, CLR выполняет компиляцию точно в срок (JIT) для преобразования кода IL в машинные инструкции.

Прежде всего давайте разберемся с определениями интерпретации и компиляции.

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

"Интерпретировать" (при ссылке на код) ТАКЖЕ означает перевод кода с одного языка на другой. Но на этот раз он обычно используется для перехода от удобочитаемого исходного кода к промежуточному коду, который берется виртуальной машиной, которая интерпретирует его в машинный код.

Просто быть чистым
Исходный код -> Компилятор -> Машинный код
Исходный код -> Компилятор -> Байт-код -> Интерпретатор -> Машинный код

Теоретически любой язык может быть интерпретирован или скомпилирован. Обычно Java компилируется в байт-код, который интерпретируется виртуальной машиной Java в машинный код. C# обычно интерпретируется как байт-код, который компилируется CLR, общеязыковой средой выполнения, другой виртуальной машиной.

Безусловно, все это маркетинговый трюк. Термин "интерпретированный" был добавлен (или, по крайней мере, увеличен в использовании), чтобы помочь продемонстрировать, насколько аккуратной была своевременная компиляция. Но они могли просто использовать "скомпилированный". Различие заключается скорее в изучении английского языка и тенденций бизнеса, чем в техническом аспекте.

C# интерпретируется и компилируется при его жизни. C# компилируется в виртуальный язык, который интерпретируется виртуальной машиной.

Путаница проистекает из нечеткой концепции "скомпилированного языка".

"Скомпилированный язык" является неправильным в некотором смысле, потому что скомпилированный или интерпретированный является не свойством языка, а средой выполнения.

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

Большинству языков, если не всем, требуется переводчик, который переводит свои сценарии в машинные коды, чтобы процессор мог понять и выполнить его!

Каждый язык обрабатывает перевод по-своему!

Например, "AutoIt" - это то, что мы можем описать как язык, интерпретируемый на 100%!

Зачем?

Потому что интерпретатор "AutoIt" ​​постоянно нужен, пока выполняется его скрипт! Смотрите пример ниже:

Loop, 1000
Any-Code

Интерпретатор "AutoIt" должен будет переводить "Any-Code" 1000 раз в машинный код, что автоматически делает "AutoIt" медленным языком!

С другой стороны, C# по-разному обрабатывает процесс перевода, интерпретатор C# требуется только один раз, перед выполнением сценария, после этого он больше не требуется во время выполнения сценария!

Интерпретатору C# придется переводить "Any-Code" только один раз в машинный код, что автоматически делает "C#" быстрым языком!

Так что в основном,

  • Язык, который требует своего интерпретатора во время выполнения скрипта, является "Интерпретируемым языком"!

  • Язык, который требует интерпретатора только один раз (перед выполнением скрипта), является "Скомпилированным языком"!

В заключение,

  • "AutoIt" - это "Интерпретированный язык"!

  • "C#" - это "скомпилированный язык"!

Я считаю, что это довольно старая тема.

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

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

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

Переводчик в Википедии

C#, как и Java, имеет гибридный языковой процессор. Гибридные процессоры выполняют задачи как интерпретации, так и компиляции.

C# является компилируемым языком.

Вероятно, я повторяю, вероятно, так как я встречал такие мнения, тот факт, что кто-то думает, что есть переводчик для языка C#, связан с такими проектами, как

Консоль переводчика C#

или, например, знаменитый

LINQPad

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

Есть реализация C#, которая является компилируемым языком.

Это остров Remobjects c#, который компилируется непосредственно в двоичный машинный код и запускается без виртуальной машины и без среды выполнения, но использует непосредственно API платформы (win32 для Microsoft, Cocoa для Apple и posix для Linux).

Кроме того, remobjects c# взаимодействует напрямую с скомпилированными библиотеками C/C++, потому что соглашение о вызовах транслируется в соглашение о вызовах c.

Поскольку компьютер может выполнять только двоичный код, любой язык приведет к созданию двоичного кода в тот или иной момент. Вопрос в том, позволяет ли язык создавать программу в двоичном коде? Если да, то это скомпилированный язык: по определению "скомпилированный" в "скомпилированном языке" относится к компиляции в двоичный код, а не к преобразованию в некоторый промежуточный код. Если язык приводит к созданию такого промежуточного кода для программы, ему потребуется дополнительное программное обеспечение для выполнения двоичной компиляции из этого кода: тогда это интерпретируемый язык. Является ли программа, "скомпилированная" с помощью C#, непосредственно исполняемой на машине без какого-либо другого программного обеспечения, установленного на этой машине? если нет, то это интерпретируемый язык. Для интерпретируемого языка это интерпретатор, который будет генерировать базовый двоичный код, в большинстве случаев динамически, поскольку этот механизм является основой гибкости таких языков. денежный перевод иногда это не выглядит очевидным, потому что переводчик включен в ОС

Здесь идут большие дебаты. Я прочитал все ответы и хочу высказать некоторые выводы, основанные на моем исследовании и концепции.

Есть понятие о.

Programming language implementation: В компьютерном программировании реализация языка программирования представляет собой систему для выполнения компьютерных программ. Существует два основных подхода к реализации языка программирования:

  1. Сборник :

    Программа читается компилятором, который переводит ее на какой-то другой язык, напримерbytecode or machine code. Переведенный код может либо выполняться аппаратно напрямую, либо служить входными данными для другого интерпретатора или другого компилятора.

  2. Интерпретация:

    Интерпретатор — это компьютерная программа, которая непосредственно выполняет инструкции, написанные на языке программирования или языке сценариев, без необходимости их предварительной компиляции в программу на машинном языке.

    • Parseисходный код и выполнять его поведение напрямую.
    • Переведите исходный код в какой-нибудь эффективныйintermediate representation or object codeи немедленно выполнить это.
    • Явноexecute stored precompiled bytecode made by a compilerи сопоставляется с виртуальной машиной интерпретатора.

Выводы:

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

Известные компилируемые языки:

  • JAVA C# C C++ GO Котлин Rust

Известные интерпретируемые языки:

  • JavaScript PHP Python

Языки с прямой компиляцией и языки, которые сначала компилируются в байт-код:

  • Интерпретаторы байт-кода (виртуальные машины), как правило, медленнее, чем прямое выполнение машинного кода. Любой интерпретатор имеет некоторые накладные расходы при преобразовании байт-кода в реальные машинные инструкции.
  • Интерпретаторы выполняют построчное выполнение.
  • Таким образом, напрямую скомпилированные языки, такие как C++/C, быстрее, чем Java/C#.
Другие вопросы по тегам