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

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

01.09.2023, 10:19. Показов 2140. Ответов 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
6504 / 5748 / 1134
Регистрация: 11.10.2019
Сообщений: 15,392
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
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
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
13223 / 6855 / 1827
Регистрация: 18.10.2014
Сообщений: 17,378
01.09.2023, 17:30
Цитата Сообщение от Optimus11 Посмотреть сообщение
Я не могу понять, эти команды не позволять включать код более, чем один раз в любой файл, в котором вызван #include ?
Да, именно так.

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

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

Но некоторые include-файлы могут быт безопасны с точки зрения повторного включения. Например, если include-файл содержит только неопределяющие объявления функций, то повторное включений такого include-файла ни на что не влияет. Теоретически, в таком include-файле не нужны include guards. Но обычно их пишут всегда, чисто машинально.
1
Нарушитель
Эксперт функциональных языков программированияЭксперт С++
6331 / 3063 / 1054
Регистрация: 01.06.2021
Сообщений: 11,698
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 / 3328 / 926
Регистрация: 25.03.2012
Сообщений: 12,545
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru