Re[4]: Нужна ли защита от повторного включения
От: удусекшл  
Дата: 10.01.22 11:06
Оценка:
Здравствуйте, B0FEE664, Вы писали:


R>>собственно мне pragma once был любопытен с точки зрения ускорения компиляции

BFE>С чего бы ему что-то ускорять?

Ну, когда компилятор видит подключение файла, он может проверить, не подключался ли он уже. Но, конечно, надо пробежаться по всем инклуд путям, чтобы сформировать полное имя файла. Но это наверное кешируется как-то


BFE>Вот как надо:

BFE>
BFE>#ifndef   ASDF_H
BFE>#include "asdf.h"
BFE>#endif
BFE>

BFE>

Я так делал, это пипецома просто
Re[3]: include guards
От: удусекшл  
Дата: 10.01.22 11:09
Оценка: +1
Здравствуйте, reversecode, Вы писали:

R>как я сделал выводы выше топиками

R>из за того что я сам не плохо контроллирую что и куда я инклудю
R>и лишних включений у меня нет, то это никак не отразится

А сколько времени у тебя уходит, чтобы не терять инклюд флоу?


R>а вот на проектах где программисты потеряли уже инклуде флов

R>и инклудят лишних хидеров
R>им бы once оптимизации явно помогли

Там программисты больше тратят времени на полезные задачи, а прагмуванс сразу вставляют
Re[3]: Нужна ли защита от повторного включения
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 10.01.22 11:31
Оценка:
Здравствуйте, reversecode, Вы писали:

R>господа линукс программисты явно не в курсе про pragma once

R>без переоптимизаций инклудов
R>банальной pragma once они бы добились тех же самых ускорений при сборке ядра

Там же сделали намного больше, чем переупорядочивание инклудов. Они ещё их переделали, разделили на части и выделили в более атомарные куски. Так что просто pragma once не помог бы.
Кроме того, использование pragma once обсуждалось не раз, но я помню, что была какая-то магия с препросессором, типа некоторые хедеры иногда надо включать по несколько раз, а иногда нет (TRACE_HEADER_MULTI_READ).
Так что только нормальный порядок и мог помочь, что, собственно, и сделали ребята.
Re: include guards
От: reversecode google
Дата: 10.01.22 12:09
Оценка:
оказывается на форуме много поклонников секты pragma once
не ожидал однако

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56549
говорят таки проблема до сих пор на гцц есть с pragma once
нет ни времени ни возможности проверять это сейчас

еще как нибудь может потестирую этот эксперимент
https://tinodidriksen.com/2011/08/cpp-include-speed/

ну и флейм от инженера интелла
https://lists.qt-project.org/pipermail/development/2018-October/033733.html
Re[5]: include guards
От: YuriV  
Дата: 10.01.22 12:14
Оценка:
Здравствуйте, Михaил, Вы писали:

М>Вообще не понимаю, почему не сделали pragma once не на основании полного пути файла, а на основании имени файла и, например, хеша содержимого. Тогда уродливые ifdef ушли бы в прошлое.


Как раз наоборот, именно на основании пути. Поэтому и получается, что две копии одного и того же файла лежащие в разных местах считаются разными файлами.
Re[4]: include guards
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 10.01.22 12:21
Оценка:
Здравствуйте, YuriV, Вы писали:

YV>Когда один и тот же файл лежит и включается из разных мест (да такое бывает в реальных проектах)


Для чего такое может быть нужно, кроме бездумного сваливания файлов в кучу?

YV>тогда в случае прагмы эти файлы будут считаться разными и естественно каждый раз включаться заново.


Зависит от. MSVC, если файлы с одинаковыми именами лежат в разных каталогах, считает их разными только при включении по #include "". При включении по #include <> файл включается только один раз. Это и правильно, учитывая установленный порядок поиска.

Другое дело, что большинство проектов, где одни заголовки включают другие, зачем-то использует форму #include <>, предназначенную для включения любого подходящего файла, вместо формы #include "", которая должна включать "свой" заголовок.
Re[5]: include guards
От: удусекшл  
Дата: 10.01.22 12:47
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Зависит от. MSVC, если файлы с одинаковыми именами лежат в разных каталогах, считает их разными только при включении по #include "". При включении по #include <> файл включается только один раз. Это и правильно, учитывая установленный порядок поиска.


ЕМ>Другое дело, что большинство проектов, где одни заголовки включают другие, зачем-то использует форму #include <>, предназначенную для включения любого подходящего файла, вместо формы #include "", которая должна включать "свой" заголовок.


Ты ерунду пишешь. Единственное отличие <> от "" — это то, что по "" компилятор сперва пытается найти такой файл относительно текущего обрабатываемого, и если обламывается, то ищет в путях инклуда, как если бы оно включалось через <>. У GCC есть, правда, возможность задавать разные наборы директорий для поиска для этих двух способов подключения, но, по-моему, никто этим особо не пользуется, я и сам как-то случайно об этом вычитал. Не в курсе, есть ли такое в MSVC и других компилерах
Re[6]: include guards
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 10.01.22 13:00
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Единственное отличие <> от "" — это то, что по "" компилятор сперва пытается найти такой файл относительно текущего обрабатываемого


Не только относительно, но и в обратном порядке по истории каталогов, содержащих включаемые файлы. То есть, поиск начинается от каталога текущего файла, и уходит "дальше" от него по истории. Поэтому, если в списке доступных каталогов указано, скажем, два независимых дерева, и какой-то заголовок из первого дерева включил "свой" файл xxx.h, содержащий pragma once, то включение из другого дерева опять же "своего" файла с тем же именем и pragma once будет успешным.

А вот если одно дерево включает "любой" xxx.h, а потом другое также включает "любой", то в обоих случаях по путям будет найден один и тот же, и включен только один раз.

То есть, если проблема коллизии имен и существует, то главным образом по причине некорректного использования форм #include в заголовках.
Re[7]: include guards
От: удусекшл  
Дата: 10.01.22 13:22
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, удусекшл, Вы писали:


У>>Единственное отличие <> от "" — это то, что по "" компилятор сперва пытается найти такой файл относительно текущего обрабатываемого


ЕМ>Не только относительно, но и в обратном порядке по истории каталогов, содержащих включаемые файлы. То есть, поиск начинается от каталога текущего файла, и уходит "дальше" от него по истории.


Не вижу ничего подобного (Из док по GCC):

By default, the preprocessor looks for header files included by the quote form of the directive #include "file" first relative to the directory of the current file, and then in a preconfigured list of standard system directories. For example, if /usr/include/sys/stat.h contains #include "types.h", GCC looks for types.h first in /usr/include/sys, then in its usual search path.

For the angle-bracket form #include <file>, the preprocessor’s default behavior is to look only in the standard system directories. The exact search directory list depends on the target system, how GCC is configured, and where it is installed. You can find the default search directory list for your version of CPP by invoking it with the -v option. For example,



Хотя, MSVC действительно делает так, как ты написал

Но, видимо, это проблемы особой не создаёт, иначе бы на GCC и MSVC напарывались на разное поведение. Я и там и там компиляю, и проблем никогда не видел


ЕМ>Поэтому, если в списке доступных каталогов указано, скажем, два независимых дерева, и какой-то заголовок из первого дерева включил "свой" файл xxx.h, содержащий pragma once, то включение из другого дерева опять же "своего" файла с тем же именем и pragma once будет успешным.


pragma once работает с абсолютным именем файла, а не тем, которое ты указал в директиве include. Так что не будет никаких проблем. Ну, или микрософт, как обычно, пошел по своему пути и облажался в очередной раз.


ЕМ>А вот если одно дерево включает "любой" xxx.h, а потом другое также включает "любой", то в обоих случаях по путям будет найден один и тот же, и включен только один раз.


ЕМ>То есть, если проблема коллизии имен и существует, то главным образом по причине некорректного использования форм #include в заголовках.


Не уверен, что существует. По крайней мере, если симлинками/хардлинками не баловаться. Не уверен, что MSVC о них знает, для винды штука довольно непривычная. А в GCC проблему вроде решили
Отредактировано 10.01.2022 13:23 удусекшл . Предыдущая версия .
Re[3]: include guards
От: Teolog  
Дата: 11.01.22 13:04
Оценка:
М>>А что не так с прагма уанс, можно вкратце, и почему это секта?

R>/somedir1/header_file.h

R>/somedir2/header_file.h

R>два хидеры с разным содержанием но одинаковым именем

R>включенные в один модуль
R>считается что при прагма онце будут проблемы

В худшем случае второй хидер не заинклудится и компилятор ругнется. На проблему не тянет.
Re[3]: Нужна ли защита от повторного включения
От: Teolog  
Дата: 11.01.22 13:08
Оценка:
Защита от повторного включения хидера по-идее не должна существенно влиять на скорость компиляции, это защита от ошибок вида "уже определено".
Re[2]: include guards
От: Teolog  
Дата: 11.01.22 13:23
Оценка: +2
Оно удобнее, а теоретические возможные проблемы относятся к категории редко-встречаемых.
То что компилятор не способен понять является ли файл тем-же если включен через другую точку монтирования — личные сексуальные проблемы авторов компилятора, при встрече будут обойдены с минимальными усилиями.
BOM появляется в файлах созданных на винде с добавлением комментариев на местном языке. Это само по себе не хорошо, кривизна GCC тут не причем, много линуксового софта такие файлы вообще не ест, ибо виндовый костыль
Re[2]: include guards
От: Shtole  
Дата: 12.01.22 04:27
Оценка:
Здравствуйте, andyp, Вы писали:

A>копипаста гардов с одинаковыми именами и убитые при редактировании эндифы в хвосте файла.


А вы чем редактируете?

Хороший редактор умеет генерировать гарды по имени создаваемого хедера (плюс рандомные элементы), а хвостовой эндиф визуально связывает с головным ифндефом, так что надо постараться, чтобы что-то сломать.
Do you want to develop an app?
Re: include guards
От: Shtole  
Дата: 12.01.22 04:28
Оценка:
Здравствуйте, reversecode, Вы писали:

R>народ на реддите в +100500 раз устроил флейм по поводу include guards


Извращенцы

Нашли, о чём спорить.
Do you want to develop an app?
Re[3]: include guards
От: andyp  
Дата: 12.01.22 07:50
Оценка: 1 (1)
Здравствуйте, Shtole, Вы писали:

S>А вы чем редактируете?


Разным. От vim до msvc через eclipse и qt creator. Где-то генерация гардов есть, где-то нет, где-то мне тупо лень ее искать.

S>Хороший редактор умеет генерировать гарды по имени создаваемого хедера (плюс рандомные элементы), а хвостовой эндиф визуально связывает с головным ифндефом, так что надо постараться, чтобы что-то сломать.


И тем не менее, регулярно получаю кучу наведенных ошибок из-за нечаянно снесенного endif.

А так, что спорить-то? Я ж всех не принуждаю переходить на прагму. Тем более, что у многих и выбора-то нет — есть корпоративные правила по оформлению кода.
Re: include guards
От: pokutan Израиль http://pokutan.com/
Дата: 14.01.22 14:55
Оценка: :)
Здравствуйте, reversecode, Вы писали:


R>итого

R>не смотря на то что писанины с pragma once меньше
R>нарваться на проблемы с одинаковыми файлами по разным путям — больше
R>останусь на старом добром ifndef

извини, но это смешно. как только ты пишешь ifndef-endif — pragma once теряет смысл, т.к. препроцессору все равно нужно теперь парсить файл до конца, чтобы найти подходящий endif.
pragma once нужно использовать без конструкции ifndef-define. естесственно, если компилятор это поддерживает.
Re[2]: include guards
От: Андрей Тарасевич Беларусь  
Дата: 15.01.22 04:50
Оценка:
Здравствуйте, pokutan, Вы писали:

P>извини, но это смешно. как только ты пишешь ifndef-endif — pragma once теряет смысл, т.к. препроцессору все равно нужно теперь парсить файл до конца, чтобы найти подходящий endif.

P>pragma once нужно использовать без конструкции ifndef-define. естесственно, если компилятор это поддерживает.

Что за белиберда? O_o

`#pragma once` обнаруживается препроцессором при первом парсинге файла, то есть тогда, когда его в любом случае придется парсить целиком. И если препроцессор поддерживает `#pragma once`, то он больше этот файл открывать и парсить не будет вообще. То есть все отлично работает именно так, как и хотелось автору кода.

`#pragma once` никак не страдает от наличия ifndef-endif. И где она размещена — внутри ifndef-endif или снаружи — не имеет никакого значения. О каком "все равно нужно теперь парсить файл до конца" вы ведете речь?
Best regards,
Андрей Тарасевич
Re[3]: include guards
От: pokutan Израиль http://pokutan.com/
Дата: 21.01.22 12:08
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, pokutan, Вы писали:


P>>извини, но это смешно. как только ты пишешь ifndef-endif — pragma once теряет смысл, т.к. препроцессору все равно нужно теперь парсить файл до конца, чтобы найти подходящий endif.

P>>pragma once нужно использовать без конструкции ifndef-define. естесственно, если компилятор это поддерживает.

АТ>Что за белиберда? O_o


АТ>`#pragma once` обнаруживается препроцессором при первом парсинге файла, то есть тогда, когда его в любом случае придется парсить целиком. И если препроцессор поддерживает `#pragma once`, то он больше этот файл открывать и парсить не будет вообще. То есть все отлично работает именно так, как и хотелось автору кода.


АТ>`#pragma once` никак не страдает от наличия ifndef-endif. И где она размещена — внутри ifndef-endif или снаружи — не имеет никакого значения. О каком "все равно нужно теперь парсить файл до конца" вы ведете речь?


Из википедии:
In the absence of #include guards around #include directives, the use of #pragma once will improve compilation speed for some compilers since it is a higher-level mechanism; the compiler itself can compare filenames or inodes without having to invoke the C preprocessor to scan the header for #ifndef and #endif.
Re[2]: include guards
От: удусекшл  
Дата: 21.01.22 13:59
Оценка:
Здравствуйте, pokutan, Вы писали:

P>извини, но это смешно. как только ты пишешь ifndef-endif — pragma once теряет смысл, т.к. препроцессору все равно нужно теперь парсить файл до конца, чтобы найти подходящий endif.


Чёй-то?
Re[4]: include guards
От: удусекшл  
Дата: 21.01.22 14:01
Оценка:
Здравствуйте, pokutan, Вы писали:

P>Из википедии:

P>In the absence of #include guards around #include directives, the use of #pragma once will improve compilation speed for some compilers since it is a higher-level mechanism; the compiler itself can compare filenames or inodes without having to invoke the C preprocessor to scan the header for #ifndef and #endif.

Тебе помочь понять написанное или попробуешь таки сам напрячься?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.