|
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
|
||||||
Что делает директива include в связке с pragma once?01.09.2023, 10:19. Показов 2009. Ответов 28
Здравствуйте,
Запутался совсем. Что делает команда #include ? Ну судя по тому, что говорит гугл - это простейшая операция скопировать-вставить, то есть берется весь код файла .cpp или .h и просто вставляется туда, где вызван #include - типа на этапе "препроцессора". Вроде бы понятно. Непонятен другой момент - есть необязательная для с++ команда компилятора "pragma once" или из стандарта:
Я не могу понять, эти команды не позволять включать код более, чем один раз в любой файл, в котором вызван #include ? Я это к тому, что говорят, что Only Header либы раздувают код, но ведь есть эти команды препроцессора, которые не позволяют включать код более одного раза ?
0
|
||||||
| 01.09.2023, 10:19 | |
|
Ответы с готовыми решениями:
28
Что делает директива #pragma Что делает директива #define ? Директива #pragma |
|
фрилансер
6465 / 5678 / 1131
Регистрация: 11.10.2019
Сообщений: 15,118
|
||
| 01.09.2023, 14:04 | ||
0
|
||
|
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
|
|||
| 01.09.2023, 14:10 | |||
![]() Важно, чтобы в никакой другой h-файл не инклудил в себя ничего. Еще раз. Я считаю, что это красивый идеал, о которм не надо забывать и к которому есть смысл мысленно стремиться. Если вы так можете сделать в проекте - значит ваши h-файлы спроектированы абсолютно правильно, можно гордиться. Красивый теоретический идеал. (как и все эти "шаблоны проектирования", "чистый код" и прочие идеализированные штуки). Это есть путь самурая. В реальной жизни - да, проще делать "как проще", спорить с этим не буду.
0
|
|||
|
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
|
||
| 01.09.2023, 14:22 | ||
|
KSergey9, если уж говорить об идеалах, то это точно не про классическую систему с заголовочными файлами. И не при чем тут как "спроектированы" заголовочные файлы - как их не проектируй описанные выше проблемы не решить фундаментально. Так что единственный путь к идеалу - это вообще не использовать эту схему h-cpp.
0
|
||
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||
| 01.09.2023, 16:34 | ||
|
твой подход вообще не дает никаких преимуществ. зато добавляет неиллюзорно геморроя.
0
|
||
|
Вездепух
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,237
|
|||
| 01.09.2023, 17:30 | |||
|
Защита от повторного включения предназначения лишь для того, чтобы не было ошибок компиляции из-за повторения тех конструкций языка, которые нельзя повторять в одной единице трансляции. Например, если в include-файле определена константа const int A = 42;, то повторное включение такого файла в одну и ту же единицу трансляции вызовет ошибку компиляции.Но некоторые include-файлы могут быт безопасны с точки зрения повторного включения. Например, если include-файл содержит только неопределяющие объявления функций, то повторное включений такого include-файла ни на что не влияет. Теоретически, в таком include-файле не нужны include guards. Но обычно их пишут всегда, чисто машинально.
1
|
|||
|
6229 / 2930 / 1047
Регистрация: 01.06.2021
Сообщений: 10,865
|
|
| 02.09.2023, 08:44 | |
|
На дворе 2023 год, а вы ссоритесь по поводу
#include.Лучше бы import обсуждали.
0
|
|
|
Комп_Оратор)
|
||
| 02.09.2023, 11:33 | ||
|
Optimus11, у включений есть одно свойство (базовое), о котором опытные не говорят (очевидно же), а новички не спрашивают (не знают, что это можно спросить). Отношения заголовков и файлов их использующих (включающих), разнятся для файлов содержащих определения для объявлений заголовков и файлов которые их просто включают для использования. Дело в том, что те файлы которые содержат определения, это "экспортёры", а те что используют - "импортёры". В С++20 это явно выражается в соответствующих ключевых словах. А в заголовках и то и другое включение выглядит синтаксически одинаково. Но в объектном файле полученном в дальнейшем из исх. файла содержащего определения объявленные в заголовке, в таблицах импорта и экспорта, указано что в данном файле есть такое-то имя "на экспорт". А в соотв. объектном файле где данный хедер с объявленным именем используется - в таблице указано, что имя предполагается"импортировать". Компилятору достаточно сигнатуры для генерации кода вызова. А вот компоновщик должен будет этот вызов в "импортирующем" объектнике, связать с кодом в соотв. файле "экспортёре". Но важно, что линкер уже работает не с исходниками, а с их объектными файлами (см. выше) и его поиск связан с просмотром таблиц и поиском нужного объектника и кода в нём для вычисления адреса вызова в адресном пространстве исполняемого модуля (exe для windows). Если в системе построения не указано явно, линкер будет искать определение в объектнике с именем соответствующем имени "экспортирующего" заголовка. Не знаю, насколько точно и понятно я выразился, если не очень то, кто-то уточнит. Однако, если этот текст не расширит круг ваших понятий, то он расширит круг ваших "непонятий", что станет стимулом для поиска информации.
3
|
||
|
|
||||||
| 07.09.2023, 12:48 | ||||||
|
Optimus11, я не понимаю, в чём тут можно запутаться.
Есть препроцессор. Работает тупо по директивам перед компиляцией. Обрабатывает строку за строкой, Встретит директиву #include - вставит файл, Встретит директиву #if - задумается, удалять или не удалять кусок кода, встретит #pragma - проверит не включался ли данный файл в текущую единицу компиляции и прекратит включение если да. Всё!!! правила просты как три копейки и исполняются как команды роботом без какой-либо проверки осмысленности и причин таких команд. То что из этих правил уже люди программисты составляют специальные include-guardы это исключительно хотелки людей. Препроцессор никогда не поймёт, чего пытался добиться человек, написавший.
- Если дойдёт до строки 1 проверить существование макроса header_H, если не существует, обработать строки 2-3, иначе не обрабатывать(и они не будут компилироваться) - Если после этого дойдёт до строки 2, добавить в набор макросов для текущую единицу компиляции макрос header_H то что в тандеме эти инструкции оберегают от повторного инклудинга - понимает только программист. а pragma once понимает препроцессор.
1
|
||||||
|
Комп_Оратор)
|
||
| 07.09.2023, 22:29 | ||
|
Бывает так, что ни гарды ни прагмы не спасают. Эти грабли можно найти только собственной ногой) Бывает что нужно связать два модуля где требуются перекрёстные ссылки и тогда спасает уже правильная структура включений. Мне известна схема включений где один из модулей в хедере делает опережающее объявление неполного типа. Это обязывает его использовать только указатели или ссылки на предобъявленного партнёра, а определения для использования в реализации делаются путём включения хедера партнёра уже в исходник (cpp например). Тогда оба заголовочника смогут жить в третьем исходнике - потребителе (main.cpp например). Конструкции #ifdef/#ifndef - тоже 'понимает' препроцессор. Но в целом, согласен с вами - #pragma once для тех компиляторов, что их понимают, компактнее. Однако, недостаток в том, что это нестандартная директива. И ещё один в том, что её работа строится на распознавании символических ссылок и может привести к проблемам. https://ru.wikipedia.org/wiki/Pragma_once
0
|
||
| 07.09.2023, 22:29 | |
|
Помогаю со студенческими работами здесь
29
Директива препроцессору #pragma
директива #pragma. модификатор volatile. и функция system() Чертовщина с #include guards и #pragma once Директива #include Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Оттенки серого
Argus19 18.03.2026
Оттенки серого
Нашёл в интернете 3 прекрасных модуля:
Модуль класса открытия диалога открытия/ сохранения файла на Win32 API;
Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
|
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога
Финальные проекты на Си и на C++:
finish-rectangles-sdl3-c. zip
finish-rectangles-sdl3-cpp. zip
|
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие.
Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
|
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ВВЕДЕНИЕ
Выполняя задание на управление насосной группой заполнения резервуара,. . .
|
|
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
|
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога
Финальные проекты на Си и на C++:
hello-sdl3-c. zip
hello-sdl3-cpp. zip
Результат:
|
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога
MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
|
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд.
Даже если у вас. . .
|