R>>собственно мне pragma once был любопытен с точки зрения ускорения компиляции BFE>С чего бы ему что-то ускорять?
Ну, когда компилятор видит подключение файла, он может проверить, не подключался ли он уже. Но, конечно, надо пробежаться по всем инклуд путям, чтобы сформировать полное имя файла. Но это наверное кешируется как-то
Здравствуйте, reversecode, Вы писали:
R>как я сделал выводы выше топиками R>из за того что я сам не плохо контроллирую что и куда я инклудю R>и лишних включений у меня нет, то это никак не отразится
А сколько времени у тебя уходит, чтобы не терять инклюд флоу?
R>а вот на проектах где программисты потеряли уже инклуде флов R>и инклудят лишних хидеров R>им бы once оптимизации явно помогли
Там программисты больше тратят времени на полезные задачи, а прагмуванс сразу вставляют
Здравствуйте, reversecode, Вы писали:
R>господа линукс программисты явно не в курсе про pragma once R>без переоптимизаций инклудов R>банальной pragma once они бы добились тех же самых ускорений при сборке ядра
Там же сделали намного больше, чем переупорядочивание инклудов. Они ещё их переделали, разделили на части и выделили в более атомарные куски. Так что просто pragma once не помог бы.
Кроме того, использование pragma once обсуждалось не раз, но я помню, что была какая-то магия с препросессором, типа некоторые хедеры иногда надо включать по несколько раз, а иногда нет (TRACE_HEADER_MULTI_READ).
Так что только нормальный порядок и мог помочь, что, собственно, и сделали ребята.
Здравствуйте, Михaил, Вы писали:
М>Вообще не понимаю, почему не сделали pragma once не на основании полного пути файла, а на основании имени файла и, например, хеша содержимого. Тогда уродливые ifdef ушли бы в прошлое.
Как раз наоборот, именно на основании пути. Поэтому и получается, что две копии одного и того же файла лежащие в разных местах считаются разными файлами.
Здравствуйте, YuriV, Вы писали:
YV>Когда один и тот же файл лежит и включается из разных мест (да такое бывает в реальных проектах)
Для чего такое может быть нужно, кроме бездумного сваливания файлов в кучу?
YV>тогда в случае прагмы эти файлы будут считаться разными и естественно каждый раз включаться заново.
Зависит от. MSVC, если файлы с одинаковыми именами лежат в разных каталогах, считает их разными только при включении по #include "". При включении по #include <> файл включается только один раз. Это и правильно, учитывая установленный порядок поиска.
Другое дело, что большинство проектов, где одни заголовки включают другие, зачем-то использует форму #include <>, предназначенную для включения любого подходящего файла, вместо формы #include "", которая должна включать "свой" заголовок.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Зависит от. MSVC, если файлы с одинаковыми именами лежат в разных каталогах, считает их разными только при включении по #include "". При включении по #include <> файл включается только один раз. Это и правильно, учитывая установленный порядок поиска.
ЕМ>Другое дело, что большинство проектов, где одни заголовки включают другие, зачем-то использует форму #include <>, предназначенную для включения любого подходящего файла, вместо формы #include "", которая должна включать "свой" заголовок.
Ты ерунду пишешь. Единственное отличие <> от "" — это то, что по "" компилятор сперва пытается найти такой файл относительно текущего обрабатываемого, и если обламывается, то ищет в путях инклуда, как если бы оно включалось через <>. У GCC есть, правда, возможность задавать разные наборы директорий для поиска для этих двух способов подключения, но, по-моему, никто этим особо не пользуется, я и сам как-то случайно об этом вычитал. Не в курсе, есть ли такое в MSVC и других компилерах
Здравствуйте, удусекшл, Вы писали:
У>Единственное отличие <> от "" — это то, что по "" компилятор сперва пытается найти такой файл относительно текущего обрабатываемого
Не только относительно, но и в обратном порядке по истории каталогов, содержащих включаемые файлы. То есть, поиск начинается от каталога текущего файла, и уходит "дальше" от него по истории. Поэтому, если в списке доступных каталогов указано, скажем, два независимых дерева, и какой-то заголовок из первого дерева включил "свой" файл xxx.h, содержащий pragma once, то включение из другого дерева опять же "своего" файла с тем же именем и pragma once будет успешным.
А вот если одно дерево включает "любой" xxx.h, а потом другое также включает "любой", то в обоих случаях по путям будет найден один и тот же, и включен только один раз.
То есть, если проблема коллизии имен и существует, то главным образом по причине некорректного использования форм #include в заголовках.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, удусекшл, Вы писали:
У>>Единственное отличие <> от "" — это то, что по "" компилятор сперва пытается найти такой файл относительно текущего обрабатываемого
ЕМ>Не только относительно, но и в обратном порядке по истории каталогов, содержащих включаемые файлы. То есть, поиск начинается от каталога текущего файла, и уходит "дальше" от него по истории.
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 проблему вроде решили
М>>А что не так с прагма уанс, можно вкратце, и почему это секта?
R>/somedir1/header_file.h R>/somedir2/header_file.h
R>два хидеры с разным содержанием но одинаковым именем R>включенные в один модуль R>считается что при прагма онце будут проблемы
В худшем случае второй хидер не заинклудится и компилятор ругнется. На проблему не тянет.
Оно удобнее, а теоретические возможные проблемы относятся к категории редко-встречаемых.
То что компилятор не способен понять является ли файл тем-же если включен через другую точку монтирования — личные сексуальные проблемы авторов компилятора, при встрече будут обойдены с минимальными усилиями.
BOM появляется в файлах созданных на винде с добавлением комментариев на местном языке. Это само по себе не хорошо, кривизна GCC тут не причем, много линуксового софта такие файлы вообще не ест, ибо виндовый костыль
Здравствуйте, andyp, Вы писали:
A>копипаста гардов с одинаковыми именами и убитые при редактировании эндифы в хвосте файла.
А вы чем редактируете?
Хороший редактор умеет генерировать гарды по имени создаваемого хедера (плюс рандомные элементы), а хвостовой эндиф визуально связывает с головным ифндефом, так что надо постараться, чтобы что-то сломать.
Здравствуйте, Shtole, Вы писали:
S>А вы чем редактируете?
Разным. От vim до msvc через eclipse и qt creator. Где-то генерация гардов есть, где-то нет, где-то мне тупо лень ее искать.
S>Хороший редактор умеет генерировать гарды по имени создаваемого хедера (плюс рандомные элементы), а хвостовой эндиф визуально связывает с головным ифндефом, так что надо постараться, чтобы что-то сломать.
И тем не менее, регулярно получаю кучу наведенных ошибок из-за нечаянно снесенного endif.
А так, что спорить-то? Я ж всех не принуждаю переходить на прагму. Тем более, что у многих и выбора-то нет — есть корпоративные правила по оформлению кода.
R>итого R>не смотря на то что писанины с pragma once меньше R>нарваться на проблемы с одинаковыми файлами по разным путям — больше R>останусь на старом добром ifndef
извини, но это смешно. как только ты пишешь ifndef-endif — pragma once теряет смысл, т.к. препроцессору все равно нужно теперь парсить файл до конца, чтобы найти подходящий endif.
pragma once нужно использовать без конструкции ifndef-define. естесственно, если компилятор это поддерживает.
Здравствуйте, pokutan, Вы писали:
P>извини, но это смешно. как только ты пишешь ifndef-endif — pragma once теряет смысл, т.к. препроцессору все равно нужно теперь парсить файл до конца, чтобы найти подходящий endif. P>pragma once нужно использовать без конструкции ifndef-define. естесственно, если компилятор это поддерживает.
Что за белиберда? O_o
`#pragma once` обнаруживается препроцессором при первом парсинге файла, то есть тогда, когда его в любом случае придется парсить целиком. И если препроцессор поддерживает `#pragma once`, то он больше этот файл открывать и парсить не будет вообще. То есть все отлично работает именно так, как и хотелось автору кода.
`#pragma once` никак не страдает от наличия ifndef-endif. И где она размещена — внутри ifndef-endif или снаружи — не имеет никакого значения. О каком "все равно нужно теперь парсить файл до конца" вы ведете речь?
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>Здравствуйте, 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.
Здравствуйте, pokutan, Вы писали:
P>извини, но это смешно. как только ты пишешь ifndef-endif — pragma once теряет смысл, т.к. препроцессору все равно нужно теперь парсить файл до конца, чтобы найти подходящий endif.
Здравствуйте, 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.
Тебе помочь понять написанное или попробуешь таки сам напрячься?