Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915

Что делает директива include в связке с pragma once?

01.09.2023, 10:19. Показов 2009. Ответов 28
Метки c++ (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте,

Запутался совсем.

Что делает команда #include ?

Ну судя по тому, что говорит гугл - это простейшая операция скопировать-вставить, то есть берется весь код файла .cpp или .h и просто вставляется туда, где вызван #include - типа на этапе "препроцессора".

Вроде бы понятно. Непонятен другой момент - есть необязательная для с++ команда компилятора "pragma once" или из стандарта:
C++
1
2
3
4
#ifndef header_H 
#define header_H
...код
#endif
Который как бы должен не позволять включать код из файла два раза.

Я не могу понять, эти команды не позволять включать код более, чем один раз в любой файл, в котором вызван #include ?

Я это к тому, что говорят, что Only Header либы раздувают код, но ведь есть эти команды препроцессора, которые не позволяют включать код более одного раза ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.09.2023, 10:19
Ответы с готовыми решениями:

Что делает директива #pragma
а именно что выполняют эти строки? можно по-простому? #pragma package(smart_init) #pragma link "trayicon" #pragma resource...

Что делает директива #define ?
Что это значит? Задача с рядом Тейлора, 0.001 - это точность разложения. Опишите подробнее, почему так можно сделать? #define EPS 0.001

Директива #pragma
Хай кто обяснит для чего нужна директива #pragma option

28
фрилансер
 Аватар для Алексей1153
6465 / 5678 / 1131
Регистрация: 11.10.2019
Сообщений: 15,118
01.09.2023, 14:04
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от KSergey9 Посмотреть сообщение
Зависит от научной школы
нет тут никакой школы, это просто минимальная необходимость. Ведь всё равно этот инклуд будет нужен повсюду, где инклудится твой инклуд. Это ООП в мире инклудов
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
01.09.2023, 14:10
Цитата Сообщение от DrOffset Посмотреть сообщение
В большом проекте это превратится в ад. Беспорядок уже будет на уровне cpp, где первые несколько экранов будут только перечислены заголовочные файлы от которых он зависит, причем в строго определенном порядке, иначе все сломается.
Это можно сложить в один h-файл и только его инклудить
Важно, чтобы в никакой другой h-файл не инклудил в себя ничего.

Еще раз.
Я считаю, что это красивый идеал, о которм не надо забывать и к которому есть смысл мысленно стремиться. Если вы так можете сделать в проекте - значит ваши h-файлы спроектированы абсолютно правильно, можно гордиться. Красивый теоретический идеал. (как и все эти "шаблоны проектирования", "чистый код" и прочие идеализированные штуки).
Это есть путь самурая.

В реальной жизни - да, проще делать "как проще", спорить с этим не буду.

Цитата Сообщение от DrOffset Посмотреть сообщение
а не обоснованная техническая потребность, лучше находиться как можно меньше.
Вы слишком скучно хотите жить
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
01.09.2023, 14:22
KSergey9, если уж говорить об идеалах, то это точно не про классическую систему с заголовочными файлами. И не при чем тут как "спроектированы" заголовочные файлы - как их не проектируй описанные выше проблемы не решить фундаментально. Так что единственный путь к идеалу - это вообще не использовать эту схему h-cpp.

Цитата Сообщение от KSergey9 Посмотреть сообщение
Вы слишком скучно хотите жить
Фанатикам нельзя доверять серьезные дела. Они все превратят в Крестовый Поход.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.09.2023, 16:34
Цитата Сообщение от KSergey9 Посмотреть сообщение
Я считаю, что это красивый идеал
какой то бессмысленный у тебя идеал.
твой подход вообще не дает никаких преимуществ.
зато добавляет неиллюзорно геморроя.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,237
01.09.2023, 17:30
Цитата Сообщение от Optimus11 Посмотреть сообщение
Я не могу понять, эти команды не позволять включать код более, чем один раз в любой файл, в котором вызван #include ?
Да, именно так.

Цитата Сообщение от Optimus11 Посмотреть сообщение
Я это к тому, что говорят, что Only Header либы раздувают код, но ведь есть эти команды препроцессора, которые не позволяют включать код более одного раза ?
... однако никакого отношения к теме "раздувания" или "не раздувания" кода include guards не имеют.

Защита от повторного включения предназначения лишь для того, чтобы не было ошибок компиляции из-за повторения тех конструкций языка, которые нельзя повторять в одной единице трансляции. Например, если в include-файле определена константа const int A = 42;, то повторное включение такого файла в одну и ту же единицу трансляции вызовет ошибку компиляции.

Но некоторые include-файлы могут быт безопасны с точки зрения повторного включения. Например, если include-файл содержит только неопределяющие объявления функций, то повторное включений такого include-файла ни на что не влияет. Теоретически, в таком include-файле не нужны include guards. Но обычно их пишут всегда, чисто машинально.
1
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6229 / 2930 / 1047
Регистрация: 01.06.2021
Сообщений: 10,865
02.09.2023, 08:44
На дворе 2023 год, а вы ссоритесь по поводу #include.
Лучше бы import обсуждали.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
02.09.2023, 11:33
Цитата Сообщение от Royal_X Посмотреть сообщение
На дворе 2023 год, а вы ссоритесь по поводу #include.
Лучше бы import обсуждали.
Никто и никогда не выбросит огромную кодовую базу построенную на заголовках и это значит, что любой будущий С++ программист обязан знать включение заголовков. Потом С++20 import/export легче будет понять.
Optimus11, у включений есть одно свойство (базовое), о котором опытные не говорят (очевидно же), а новички не спрашивают (не знают, что это можно спросить).
Отношения заголовков и файлов их использующих (включающих), разнятся для файлов содержащих определения для объявлений заголовков и файлов которые их просто включают для использования. Дело в том, что те файлы которые содержат определения, это "экспортёры", а те что используют - "импортёры". В С++20 это явно выражается в соответствующих ключевых словах.
А в заголовках и то и другое включение выглядит синтаксически одинаково. Но в объектном файле полученном в дальнейшем из исх. файла содержащего определения объявленные в заголовке, в таблицах импорта и экспорта, указано что в данном файле есть такое-то имя "на экспорт". А в соотв. объектном файле где данный хедер с объявленным именем используется - в таблице указано, что имя предполагается"импортировать". Компилятору достаточно сигнатуры для генерации кода вызова. А вот компоновщик должен будет этот вызов в "импортирующем" объектнике, связать с кодом в соотв. файле "экспортёре". Но важно, что линкер уже работает не с исходниками, а с их объектными файлами (см. выше) и его поиск связан с просмотром таблиц и поиском нужного объектника и кода в нём для вычисления адреса вызова в адресном пространстве исполняемого модуля (exe для windows).
Если в системе построения не указано явно, линкер будет искать определение в объектнике с именем соответствующем имени "экспортирующего" заголовка.
Не знаю, насколько точно и понятно я выразился, если не очень то, кто-то уточнит. Однако, если этот текст не расширит круг ваших понятий, то он расширит круг ваших "непонятий", что станет стимулом для поиска информации.
3
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
07.09.2023, 12:48
Optimus11, я не понимаю, в чём тут можно запутаться.
Есть препроцессор.
Работает тупо по директивам перед компиляцией.
Обрабатывает строку за строкой, Встретит директиву #include - вставит файл, Встретит директиву #if - задумается, удалять или не удалять кусок кода, встретит #pragma - проверит не включался ли данный файл в текущую единицу компиляции и прекратит включение если да.
Всё!!! правила просты как три копейки и исполняются как команды роботом без какой-либо проверки осмысленности и причин таких команд.
То что из этих правил уже люди программисты составляют специальные include-guardы
это исключительно хотелки людей.
Препроцессор никогда не поймёт, чего пытался добиться человек, написавший.
C++
1
2
3
4
#ifndef header_H 
#define header_H
...код
#endif
для него это 2-3 отдельные частные инструкции без какого-либо общего смысла
- Если дойдёт до строки 1 проверить существование макроса header_H, если не существует, обработать строки 2-3, иначе не обрабатывать(и они не будут компилироваться)
- Если после этого дойдёт до строки 2, добавить в набор макросов для текущую единицу компиляции макрос header_H

то что в тандеме эти инструкции оберегают от повторного инклудинга - понимает только программист.
а pragma once понимает препроцессор.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
07.09.2023, 22:29
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Optimus11, я не понимаю, в чём тут можно запутаться.
М-можно! неожиданно сказал дворник./12 стульев/
Бывает так, что ни гарды ни прагмы не спасают. Эти грабли можно найти только собственной ногой) Бывает что нужно связать два модуля где требуются перекрёстные ссылки и тогда спасает уже правильная структура включений. Мне известна схема включений где один из модулей в хедере делает опережающее объявление неполного типа. Это обязывает его использовать только указатели или ссылки на предобъявленного партнёра, а определения для использования в реализации делаются путём включения хедера партнёра уже в исходник (cpp например). Тогда оба заголовочника смогут жить в третьем исходнике - потребителе (main.cpp например).
Конструкции #ifdef/#ifndef - тоже 'понимает' препроцессор. Но в целом, согласен с вами - #pragma once для тех компиляторов, что их понимают, компактнее. Однако, недостаток в том, что это нестандартная директива. И ещё один в том, что её работа строится на распознавании символических ссылок и может привести к проблемам.
https://ru.wikipedia.org/wiki/Pragma_once
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.09.2023, 22:29
Помогаю со студенческими работами здесь

Директива препроцессору #pragma
Что это за директива такая? Для чего предназначена? Если не затруднит, можно привести примеры?

Директива препроцессора pragma
Добрый день! Помогите, пожалуйста, не могу понять смысл такой записи. (интересуют строки с участием _PACKED(строки 2-6 и 51-60), и что...

директива #pragma. модификатор volatile. и функция system()
Всем привет! Скажите пожалуйста что делает директива #pragma Я знаю, что её значение зависит от компилятора, тогда подскажите где...

Чертовщина с #include guards и #pragma once
Господа, у меня тут творится какая-то хрень: что бы я ни делал, h-файл инклудится дважды и константы, описанные в нём, в разных модулях...

Директива #include
Всем привет. Пишу программу по книге Дейтел Х., Дейтел П - Как программировать на C++ FIG6_5.cpp, я компилирую проект FIG6_5.dev вместе с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
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
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru