Чем отличается компиляция c ++ / c # / java? - PullRequest
4 голосов
/ 08 сентября 2010

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

C ++:

Компилятор C ++ предварительно обрабатывает все исходные файлы.Это означает, что он на самом деле вставляет строки в те места, где макросы изначально.После этого он создает файл .obj для каждого исходного файла, содержащий независимый от машины байт-код.Затем компоновщик связывает все внешние файлы .obj из библиотек с пользовательскими файлами .obj и объединяет их в .exe.

Java:

Java-код компилируется в независимый от компьютера "bytecode ", который находится в файлах .class, которые, в свою очередь, могут находиться в файлах .JAR, которые запускаются на JRE.Виртуальная машина просто выполняет очистку от мусора.Код Java компилируется точно в срок, как C #, но с оптимизацией горячей точки, разработанной SUN.

C #:

Практически так же, как Java?Исходный код C # компилируется в код CIL (Common Intermediate Language), который все еще доступен для чтения человеком.Этот код будет выполняться CLR Just-in-Time.Эта компиляция превращает методы в машинно-специфический код, когда они впервые вызываются.

Я на самом деле интересуюсь почти каждым языком ... но Java и C # почти одинаковы, и мне всегда было интересно, как дифференцировать,А С ++ - это, так сказать, «классика».Отец обоих без какой-либо виртуальной машины.Спасибо за помощь!

edit: Я знаю, что это обширная тема, но я действительно не мог найти никаких твердых знаний.Если у вас есть ссылки или книги, объясняющие подобные вещи, я с удовольствием пойду на работу.Я попытался прочитать спецификации / технические документы SUN для виртуальной машины Java, но сейчас все это слишком глубоко для меня.

Ответы [ 3 ]

6 голосов
/ 08 сентября 2010

Компиляция неуправляемого C ++ очень отличается от компиляции управляемого C ++, C # и Java.

Неуправляемый C ++

Неуправляемый C ++ («традиционный» C ++)компилируется непосредственно в машинный код .Программист вызывает компилятор, предназначенный для конкретной платформы (процессор и операционная система), и компилятор выводит исполняемый файл, который работает только на этой платформе.Исполняемый файл содержит машинный код, который понимает конкретный процессор.При выполнении процессор непосредственно выполняет скомпилированный код как есть (преобразование адреса виртуальной памяти по модулю yadda yadda).

Управляемый C ++, C # и Java

Управляемый код компилируется в промежуточный код (CIL в случае языков .NET, таких как C #, и байт-код Java в случае Java).Компилятор выводит исполняемый файл, содержащий код на этом промежуточном языке.На данный момент он все еще не зависит от платформы.При выполнении запускается так называемый Just-in-Time компилятор , который переводит промежуточный код в машинный код непосредственно перед выполнением.Затем процессор выполнит машинный код, сгенерированный компилятором JIT.В большинстве случаев этот машинный код хранится в памяти и сбрасывается в конце программы (поэтому в следующий раз он должен снова запустить JITting), но существуют инструменты для постоянного выполнения JITting.

Преимущество здесь, конечно, в том, что независимый от платформы исполняемый файл может быть запущен на любой платформе, но недостатком является то, что вам нужна среда выполнения (включая JIT-компилятор) для этой платформы .

1 голос
/ 08 сентября 2010

Довольно хорошо.

.obj файлы C ++ зависят от компьютера, но обычно не имеют разрешенных адресов памяти. Линкер просто берет файлы .obj, связывает их вместе и разрешает многие адреса в абсолютные значения.

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

Я думаю, что все остальное довольно правильно - хотя я не могу честно сказать, является ли CIL C # читабельным для человека.

0 голосов
/ 08 сентября 2010

Все три языка в значительной степени одинаковы (все они являются обязательными языками OO), основные отличия заключаются в том, что

  • Java и C # поддерживают отражение типов во время выполнения (т. Е. Программа можетисследуйте себя, и приведение типов - это проверенные во время выполнения операции), в то время как C ++ не делает и
  • вы не можете подрывать типы Java и C # непосредственно из самих языков (хотя я подозреваю, что компиляторы для всех трех языковпросто генерировать код с неопределенной семантикой в ​​исключительных случаях);
  • C ++ не должен проверять разыменования NULL (это оставлено аппаратному обеспечению), тогда как C # и Java должны проверять нулевые значения при каждом разыменовании;
  • C # и Java должны обеспечивать более строгие гарантии в отношении модели памяти (т. Е. Что происходит в случае одновременного чтения / записи в одну и ту же переменную), обработки исключений и т. Д .;
  • обычно C ++ компилируется непосредственно на целевой машине или языке ассемблера, тогда как C # и Javaобычно компилируется в промежуточные языки (IL или JVM) для последующего JITting или интерпретации.IL и JVM, по сути, являются абстракциями «ЦП».

Компилятор C ++ пойдет на все, чтобы оптимизировать код, который он генерирует, потому что он не может выдержать нагрузку для низкоуровневой оптимизации.на JIT-компиляторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...