Разница между объектом кода и исполняемым файлом
Я новичок 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
Код объекта (внутри объектного файла): вывод компилятора, предназначенного для ввода компоновщика (для компоновщика для создания исполняемого кода).
Исполняемый файл: программа, готовая к запуску (выполнение) на компьютере