Директивы препроцессора C++

Директивы препроцессора C++

Проекты компиляторов можно классифицировать по следующим критериям. Для работы с компилятором удобнее всего использовать какой-нибудь дистрибутив Linux, но если вы твердо решили изучать программирование на Windows, то лучшим выбором будет некоммерческая версия среды разработки QtCreator с QtSDK, ориентированная на MinGW.

Вам просто нужно быть внимательными и выбрать версию, ориентированную на MinGW. Если специально не указано иное, мы, вероятно, будем использовать компилятор, входящий в дистрибутив Linux. Коллекция компиляторов GNU включает в себя несколько языков. Из них группа языков C состоит из трех компиляторов. Его следует поставить и указать с помощью ключа -l compilation. После препроцессора файлы компиляции обычно значительно увеличиваются в размере, но теперь они содержат все, что нужно компилятору для создания объектного файла.

Компиляция - это процесс превращения текстов на языке ассемблера в объектные файлы. Это файлы, состоящие из кода целевого процессора, но еще не имеющие адресов объектов в других объектных файлах или библиотеках. Связывание - процесс объединения объектных файлов проекта и используемых библиотек в единую целевую сущность для целевой платформы. Это может быть исполняемая программа, статическая или динамическая библиотека.

Препроцессинг Препроцессинг - процедура, ставшая традиционной во многих обработчиках различного рода описаний, в том числе текстов с программным кодом. В общем случае, когда требуется предварительная обработка текстов, реализуется некоторый язык препроцессирования, элементы которого оцениваются препроцессором при обработке файла. Основными элементами языка препроцессора являются директивы и макросы.

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

Препроцессор предназначен для выполнения таких замен. Часто препроцессор вводит файл с несколькими десятками строк, а на выходе получается список компиляции из десятков тысяч строк.

Сборка С одной стороны, процесс сборки довольно прост для понимания, а с другой стороны, он наиболее сложен для реализации. По своей сути, это процесс перевода выражений с одного языка на другой.

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

В данном случае мы просто увидели общий подход в архитектуре проекта GNU Compiler Collection. Чтобы максимально объединить разные языки в одной коллекции, каждый язык реализует свой собственный транслятор языка ассемблера и препроцессор, если это необходимо, в то время как компилятор языка ассемблера и компоновщик являются общими для всех языков коллекции. Компиляция В данном случае мы имеем компилятор языка ассемблера. В результате получается объектный файл, основанный на всем тексте, который был предоставлен в списке компиляции.

Поэтому мы можем сказать, что каждый объектный файл в проекте соответствует одному списку компиляции проекта. Объектный файл - это двоичный файл, который фактически состоит из набора функций.

Однако не все вызываемые функции из исходного листа компиляции имели реализацию или определение. Это не следует путать с декларацией. Для того чтобы лист компиляции был компилируемым, все вызываемые функции должны иметь декларации в листе компиляции, прежде чем их можно будет использовать. Однако декларация - это не более чем имя функции и параметры вызова, которые позволяют правильно сформировать стек во время компиляции для передачи переменных для вызова функции и отметить, что здесь должна быть вызвана функция с указанным именем, адрес реализации которой еще не известен.

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

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

Эти объявления должны существовать до использования сущностей. В противном случае компилятор не сможет подготовить ссылку на сущность. Например, он не сможет передать параметры через стек вызова функции и подготовиться к приему возвращаемого значения функции. Связывание На этапе связывания все объектные файлы в проекте, скомпилированные из соответствующих листов компиляции в проекте, объединяются в единую сущность.

Это может быть приложение, статическая библиотека или динамическая библиотека. Разница заключается в двоичных заголовках целевых файлов и несколько иной внутренней организации. Основная задача линковки - заменить адреса вызова внешних объектов, которые были созданы в объектных файлах проекта.

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

GNU Toolchain - Старейшая система сборки проектов, до сих пор известная по комбинации команд configure-make-"make install". CMake - кроссплатформенная система сборки, позволяющая не только создать кроссплатформенный проект, но и создать скрипт компиляции для любой известной среды разработки, имеющей генераторы скриптов.

QMake - довольно простая система сборки, специально реализованная для фреймворка Qt и широко используемая именно для сборки Qt-проектов. Имеет некоторые проблемы с обнаружением сложных метакомпиляционных зависимостей, специфичных для Qt, поэтому даже в проектах Qt рекомендуется использовать систему сборки CMake. Современные версии QtCreator могут работать с проектами, использующими как систему сборки QMake, так и CMake. Для компиляции мы будем использовать консоль для написания прямых команд компиляции.

Это даст нам лучшее представление о шагах компиляции, описанных выше. Итак, давайте создадим файл с именем main. Первая строка кода содержит директиву включения в проект файла с именем iostream. В этом случае препроцессор, обнаружив директиву include file, включит все строки из указанного в директиве файла в позицию инструкции include в тексте программы.

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

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

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

В нашем случае мы их не используем. В строке 5 мы обращаемся к предопределенному объекту cout из пространства имен std, который связан с выходным потоком приложения. Используя синтаксис, определенный для этого объекта, мы передаем строку "Hello world" и символ возврата каретки и перевода строки. В строке 7 мы возвращаем строку 0 в качестве кода возврата для функции main.

При организации процесса в операционной системе это число будет считаться кодом возврата для приложения. Следующий шаг в нашем эксперименте - прекратить компиляцию главного файла. Нам не нужно писать знак доллара. Давайте запустим его и посмотрим на результат. При запуске на операционной системе Windows результатом компиляции будет файл с расширением exe. Скорее всего, он будет называться main.

Навигация

thoughts on “Директивы препроцессора C++

  • Я предполагаю ориентироваться при выборе лишь на свой вкус. Никаких других критериев для выкладываемой в тэом блоге музыки не будет. Что-то по-моему мнению больше подходит для утреннего прослушивания. Чот-то - для вечернего.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *