Разница между объектом кода и исполняемым файлом

Я новичок C++, и я изучаю основы языка. В моей книге есть тема о компиляторе, и моя проблема в том, что я не могу понять, что текст хочет сказать:

C++ - это скомпилированный язык, поэтому вам нужно перевести исходный код в файл, который компьютер может выполнить. Этот файл генерируется компилятором и называется объектным кодом (.obj), но программа, подобная программе "hello world", составлена частью, которую мы написали, и частью библиотеки C++. Компонент связывает эти две части программы и создает исполняемый файл (.exe).

Почему в моей книге говорится, что файл, который выполняется на компьютере, является тем, у которого есть суффикс obj (объектный код), а затем сказать, что он является экземпляром exe?

Ответ 1

Объектные файлы скомпилированы исходным кодом в двоичный машинный язык, но они содержат нерешенные внешние ссылки (например, printf, например). Возможно, они должны быть связаны с другими объектными файлами, сторонними библиотеками и почти всегда с библиотекой времени выполнения C/C++.

В Unix оба файла object и exe имеют одинаковый формат COFF. Единственное различие заключается в том, что объектные файлы имеют нерешенные внешние ссылки, а файлы a.out - нет.

Ответ 2

Спецификация C++ является техническим документом на английском языке. Для C++ 11 загляните внутрь n3337 (или потратите много денег, чтобы купить стандарт ISO обложки в мягкой обложке). Теоретически вам не нужен компьютер для запуска программы C++ (вы могли бы использовать кучу человеческих рабов, но это было бы неэтично, неэффективно и ненадежно).

У вас может быть реализация C++, которая является интерпретатором, а не компилятором (например, Ch by SoftIntegration)

Если вы устанавливаете Linux на свой ноутбук (что я рекомендую делать каждому учащемуся), то у вас может быть несколько компиляторов свободного программного обеспечения C++, в частности GCC и Clang/LLVM (с использованием g++ и clang соответственно). Исходные файлы имеют суффикс .cc или .cxx или .cpp или даже .C (я предпочитаю .cc), и вы можете попросить компилятор обработать файл какого-либо другого суффикса в качестве C++ исходного файла (но это не является обычным). Затем оба объектных файла (суффикс .o) и исполняемые файлы имеют один и тот же формат ELF. Обычно исполняемые файлы не имеют никакого суффикса (например, g++ является бинарным исполняемым файлом, не делая ничего, кроме запуска других процессов, таких как cc1plus -the proper-, as -the ассемблер, ld -the компоновщик - и т.д....)

Во всех случаях я настоятельно рекомендую:

  • для включения всех предупреждений и информации об отладке во время компиляции (например, используйте g++ -Wall -g....)
  • улучшить исходный код до тех пор, пока вы не получите никаких предупреждений
  • узнать, как использовать отладчик (gdb)
  • для возможности создания вашей программы в командной строке
  • использовать систему управления версиями, такую как git
  • использовать хороший редактор, например emacs, gedit, geany или gvim
  • как только вы пишете программы в нескольких исходных файлах, узнайте, как использовать построитель, например make
  • изучить C++ 11 (или даже, возможно, C++ 14), а не более старые C++ стандарты
  • а также изучать другие языки программирования (Ocaml, Scheme, Haskell, Prolog, Scala,....), поскольку они улучшат ваше мышление и ваш способ кодирования в C++
  • для изучения исходного кода нескольких свободных программ, закодированных в C++
  • читать документацию по каждой функции, которую вы используете, например, на cppreference или в man-страницах (для Linux)
  • чтобы понять, что такое неопределенное поведение (тот факт, что ваша программа иногда работает, не делает ее правильной).

Конкретно, в Linux вы можете редактировать свою программу Hello World (файл hello.cc) с помощью gedit или emacs (с помощью команды gedit hello.cc) и т.д...., скомпилируйте ее с помощью g++ -Wall -g hello.cc -o hello command, отлаживайте его с помощью gdb./hello и повторите (не забудьте использовать команды git для контроля версий).

Иногда имеет смысл генерировать некоторый код C++, например, с помощью какого-либо сценария оболочки, Python или awk (или даже вашей собственной программы, закодированной в C++, которая генерирует код C++!).

Кроме того, поймите, что IDE не является компилятором (но запускает для вас компилятор).

Ответ 3

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

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

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

Затем люди создали языки программирования, которые больше похожи на людей, написанных на языках, а не на ассемблере (например, FORTRAN и COBOL и ALGOL). Эти языки легче читать, и одна строка источника может быть преобразована в несколько машинных команд, поэтому было более продуктивно писать компьютерные программы на этих языках, а не на ассемблере.

Язык программирования C был позднее уточнением, используя уроки, извлеченные из ранних языков программирования, таких как FORTRAN. И C использовал некоторые из тех же самых инструментов разработки программного обеспечения, которые уже существовали, например, линкеры, которые уже существовали. Еще позже C++ был изобретен, начиная с усовершенствования C, представляющего объекты, ориентированные на объекты. На самом деле первый C++ компилятор был действительно C++ переводчиком, который перевел исходный код C++ в исходный код C, который затем был скомпилирован с компилятором C. Однако современный C++ скомпилирован прямо к машинным кодам, чтобы обеспечить полную функциональность стандарта C++ шаблонами, лямбдами и другими вещами с помощью C++ 11 и более поздних версий.

Основные шаги для создания приложения из исходного файла C или C++: (1) создаются исходные файлы, (2) скомпилированы исходные файлы (что на самом деле два этапа, препроцессор и компиляция), ( 3) объектные файлы, созданные компилятором C/C++, связаны с созданием.exe

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

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

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

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

Ответ 4

Код объекта (внутри объектного файла): вывод компилятора, предназначенного для ввода компоновщика (для компоновщика для создания исполняемого кода).

Исполняемый файл: программа, готовая к запуску (выполнение) на компьютере