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

V>В pragma once просто нет смысла, если стоит страж включения ifndef-define-endif. Я себя раньше спрашивал, а зачем я прописываю и то и другое. В итоге забил и оставил лишь страж включения. Но это было очень давно, тогда pragma once ещё не стала практически стандартом.


Теоретически, pragma once должна быть быстрее, так как компилятор даже не будет открывать повторно этот файл, а в случае с гардами таки надо препроцессировать. Поэтому — pragma once. А гарды — на всякий случай, вдруг попадётся компилятор, в котором её нет. Хотя, конечно, это маловероятно, поэтому я стал ленится делать гарды
Re[4]: include guards
От: Андрей Тарасевич Беларусь  
Дата: 21.01.22 16:54
Оценка:
Здравствуйте, pokutan, Вы писали:

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

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

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


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


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


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.

Так это обычная чушь из википедии. Я уже опроверг ее в своем предыдущем сообщении.

Во-первых, википедия — "мусорный" источник. Поэтому не ясно, к чему вы здесь это цитируете.

Во-вторых, справедливости ради, можно попытаться сыграть "адвоката дьявола" и заметить, что в процитированном пассаже ничего не сказано о том, что будет "in the presence of #include guards", то есть процитированный пассаж совсем не несет того смысла, который вы ему пытаетесь навязать ))) Разумеется, это будет не более чем натягиванием совы на глобус, ибо на само деле в википедии просто написана чушь.
Best regards,
Андрей Тарасевич
Отредактировано 21.01.2022 17:02 Андрей Тарасевич . Предыдущая версия .
Re[5]: Нужна ли защита от повторного включения
От: Андрей Тарасевич Беларусь  
Дата: 21.01.22 17:01
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Теоретически, pragma once должна быть быстрее, так как компилятор даже не будет открывать повторно этот файл, а в случае с гардами таки надо препроцессировать. Поэтому — pragma once. А гарды — на всякий случай, вдруг попадётся компилятор, в котором её нет. Хотя, конечно, это маловероятно, поэтому я стал ленится делать гарды


`#pragma once` не выжила именно именно потому, что в %99.9 случаев использование include guards является тотальным по отношению к включаемому файлу, то есть полностью функционально эквивалентным `#pragma once`. Такое использование include guards легко распознается препроцессором, который в такой ситуации не будет делать никакого "повторного открытия" и ничего препроцессировать заново не будет.

Другими словами, если препроцессор в состоянии реализовать предполагаемую функциональность `#pragma once`, то он в состоянии реализовать все это и без `#pragma once`- на основе умной обработки include guards. Именно потому от `#pragma once` и отказались.
Best regards,
Андрей Тарасевич
Отредактировано 21.01.2022 17:04 Андрей Тарасевич . Предыдущая версия . Еще …
Отредактировано 21.01.2022 17:03 Андрей Тарасевич . Предыдущая версия .
Отредактировано 21.01.2022 17:03 Андрей Тарасевич . Предыдущая версия .
Re[6]: Нужна ли защита от повторного включения
От: Shtole  
Дата: 21.01.22 17:25
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>`#pragma once` не выжила <…> от `#pragma once` и отказались.


А что значит «не выжила»? И где отказались?
Do you want to develop an app?
Re[6]: Нужна ли защита от повторного включения
От: VladFein США  
Дата: 21.01.22 17:33
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

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


У>>Теоретически, pragma once должна быть быстрее, так как компилятор даже не будет открывать повторно этот файл, а в случае с гардами таки надо препроцессировать. Поэтому — pragma once. А гарды — на всякий случай, вдруг попадётся компилятор, в котором её нет. Хотя, конечно, это маловероятно, поэтому я стал ленится делать гарды


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


АТ>Другими словами, если препроцессор в состоянии реализовать предполагаемую функциональность `#pragma once`, то он в состоянии реализовать все это и без `#pragma once`- на основе умной обработки include guards. Именно потому от `#pragma once` и отказались.


Вы говорите, что компилятор "хранит" пре-процессед инклуды?
Я не понимаю такой момент: когда компилятор встречает
#include "x.h"
он ДОЛЖЕН открыть этот файл? И, встретив #ifdef — должен найти парный #endif?
И это все — даром (по времени)?
Re[7]: Нужна ли защита от повторного включения
От: Андрей Тарасевич Беларусь  
Дата: 21.01.22 20:19
Оценка: :)
Здравствуйте, Shtole, Вы писали:

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


АТ>>`#pragma once` не выжила <…> от `#pragma once` и отказались.


S>А что значит «не выжила»? И где отказались?


Я говорю про языки С и С++. `#pragma once` когда-то рассматривалась для стандартизации. Одну из основных причин, по которой от нее отказались, я привел выше.

С тех пор уже много времени прошло. Все уже забыли, что когда-то была такая `#pragma once`.
Best regards,
Андрей Тарасевич
Re[7]: Нужна ли защита от повторного включения
От: Андрей Тарасевич Беларусь  
Дата: 21.01.22 20:33
Оценка:
Здравствуйте, VladFein, Вы писали:

У>>>Теоретически, pragma once должна быть быстрее, так как компилятор даже не будет открывать повторно этот файл, а в случае с гардами таки надо препроцессировать. Поэтому — pragma once. А гарды — на всякий случай, вдруг попадётся компилятор, в котором её нет. Хотя, конечно, это маловероятно, поэтому я стал ленится делать гарды


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


АТ>>Другими словами, если препроцессор в состоянии реализовать предполагаемую функциональность `#pragma once`, то он в состоянии реализовать все это и без `#pragma once`- на основе умной обработки include guards. Именно потому от `#pragma once` и отказались.


VF>Вы говорите, что компилятор "хранит" пре-процессед инклуды?


Не понял. Я не знаю, что делает ваш компилятор. И зачем "хранить пре-процессед инклуды"? Что такое "хранить пре-процессед инклуды"?

Я лишь говорю, что вся идея, вся суть `#pragma once` заключается именно и только в том, чтобы хранить имена (или внутренние уникальные идентификаторы) уже просмотренных в данной единице трансляции инклудов и не открывать и не парсить их второй раз. Как же еще? Хранить нужно только уникальные идентификаторы файлов (имена, inode иди что-то в этом роде). Никакие "пре-процессед инклуды" хранить не нужно.

Если какой-то компилятор умеет такое делать для `#pragma once`, то он прекрасно сумеет это сделать и для тривиальных применений include guards. То есть никакого преимущества `#pragma once` не предоставляет (кроме того, что в include guards нужно придумывать как-то уникальное макро).

VF>Я не понимаю такой момент: когда компилятор встречает

VF>#include "x.h"
VF>он ДОЛЖЕН открыть этот файл? И, встретив #ifdef — должен найти парный #endif?
VF>И это все — даром (по времени)?

Кому "должен"?

См. выше. Если компилятор уверен, что этот `#include "x.h"` ссылается на уже пропарсенный в этой единице трансляции файл, и в этом файле содержится `#pragma once` или тривиальные include guards, то он может второй раз его не открывать и не парсить. Зачем?

Но это все — вопрос качества реализации, которые пользователя не касаются. Вы просто не будете знать, открывал он его второй раз или нет. Вам это не нужно знать.
Best regards,
Андрей Тарасевич
Отредактировано 21.01.2022 21:03 Андрей Тарасевич . Предыдущая версия . Еще …
Отредактировано 21.01.2022 21:02 Андрей Тарасевич . Предыдущая версия .
Отредактировано 21.01.2022 21:02 Андрей Тарасевич . Предыдущая версия .
Отредактировано 21.01.2022 20:49 Андрей Тарасевич . Предыдущая версия .
Отредактировано 21.01.2022 20:34 Андрей Тарасевич . Предыдущая версия .
Re[8]: Нужна ли защита от повторного включения
От: Shtole  
Дата: 21.01.22 20:34
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Я говорю про языки С и С++. `#pragma once` когда-то рассматривалась для стандартизации. Одну из основных причин, по которой от нее отказались, я привел выше.


А… Стандарт с большой буквы Сэ… Понятно.

АТ>С тех пор уже много времени прошло. Все уже забыли, что когда-то была такая `#pragma once`.


Студия помнит. Авторы библиотек с гитхаба, которые в прошлом году понадобились, тоже.
Do you want to develop an app?
Re[9]: Нужна ли защита от повторного включения
От: Андрей Тарасевич Беларусь  
Дата: 21.01.22 20:46
Оценка:
Здравствуйте, Shtole, Вы писали:

АТ>>С тех пор уже много времени прошло. Все уже забыли, что когда-то была такая `#pragma once`.


S>Студия помнит.


Много кто "помнит". Как я говорил выше, когда-то была реальная попытка стандартизации `#pragma once`, по каковой причине неудивительно, что многие компиляторы бросились ее реализовывать авансом. Но затея с стандартизацией накрылась медным тазом, а реализации в компиляторах так и живут, как рудименты тех времен.

S>Авторы библиотек с гитхаба, которые в прошлом году понадобились, тоже.


За использование голого `#pragma once` — без страховки через include guards — "библиотека с гитхаба" сразу идет ффтопку под взрывы гомерического смеха окружающих. Никому такая библиотека не нужна.

А в остальных случаях `#pragma once` — это карго-культ. Одни "авторы библиотек с гитхаба" подсмотрели (читай: скопипастили) это у других "авторов библиотек с гитхаба". Те в свое время — у третьих и т.д. Они и сами не знают, зачем они это делают. Многие из них, возможно, даже в курсе, что `#pragma once` ничего не дает (по сравнению с include guards), но продолжают механически следовать карго-культу.
Best regards,
Андрей Тарасевич
Отредактировано 21.01.2022 21:27 Андрей Тарасевич . Предыдущая версия . Еще …
Отредактировано 21.01.2022 20:47 Андрей Тарасевич . Предыдущая версия .
Отредактировано 21.01.2022 20:46 Андрей Тарасевич . Предыдущая версия .
Re[5]: include guards
От: Андрей Тарасевич Беларусь  
Дата: 23.01.22 03:52
Оценка: +1 -1
Здравствуйте, Евгений Музыченко, Вы писали:

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


Чего? В С и С++ форма `#include <>` вообще не имеет никакого отношения ни к каким файлам. То, что указывается в треугольных скобках — это не файл вообще. Если используемая вам реализация реализует стандартные заголовки через файлы — флаг ей в руки, но не о каком "предназначенную для включения любого подходящего файла" речи быть не может.
Best regards,
Андрей Тарасевич
Re: include guards
От: 5.März  
Дата: 23.01.22 05:09
Оценка: +1
Здравствуйте, reversecode, Вы писали:

R>вообщем то я не поклонник секты pragma once


Сектантство — это как раз делать менее удобный для себя выбор по убеждениям ("все что не в стандарте — в топку"), несмотря на перевес "за-против" в пользу противоположного.

Сам факт того, что эта тема вызывает холивар, является косвенным указанием, что в прагме есть своя ценность. На обсуждение настоящей туфты никто бы своего времени тратить не стал.

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


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

По ущербности эта логика мне напоминает аргумент, что система сборки должна требовать вручную прописывать каждый файл, и ей нельзя автоматически компилировать все файлы в папке, потому что "а вдруг один из файлов в папке это мусор"? У тех у кого в папках проекта незаметно проскакивает мусор проблемы куда больше и серьезнее, чем выбор системы сборки — им надо над дисциплиной и над тестами работать, а не выбирать тулсы с прицелом на плохую дисциплину.

Люди фокусируются на совершенно пустяковом выборе между A и Б и в упор не видят, что само наличие разницы является симптомом куда большей проблемы на уровне выше. Если компилируемость вашего проекта зависит от выбора между прагмой и гардами, вы либо делаете что-то очень экзотическое (вероятность 0.1%) либо делаете что-то сильно не так (99.9%)
Re: include guards
От: Sm0ke Россия ksi
Дата: 23.01.22 08:23
Оценка:
Использую #pragma once
gcc кушает, и ладно

С модулями вообще без инклюдов можно обойтись, но к сожалению в gcc есть баги по модулям.
Жду, когда Circle получит порт под win и туда добавят модули. Или пофиксят gcc.
Re[6]: include guards
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.01.22 11:34
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>В С и С++ форма `#include <>` вообще не имеет никакого отношения ни к каким файлам.


Соответствующий раздел стандарта называется "Source file inclusion".
Re[7]: include guards
От: Андрей Тарасевич Беларусь  
Дата: 23.01.22 18:20
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

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


АТ>>В С и С++ форма `#include <>` вообще не имеет никакого отношения ни к каким файлам.


ЕМ>Соответствующий раздел стандарта называется "Source file inclusion".


Мало ли, как он называется. Раздел, описывающий функцию `memcpy` называется "String handling". Это, однако, совсем не означает, что эти функция `memcpy` предназначены для работы со строками.

Уже первые строчки раздела "Source file inclusion" вводят разделение между "header" и "source file": "A #include directive shall identify a header or source file that can be processed by the implementation." "Header" — это не "source file", а существенно более общее и абстрактное понятие.

Директива c <> включает хедеры.
Директива c "" включает файлы и, если файл не найден, ищет хедеры.
Best regards,
Андрей Тарасевич
Re[2]: include guards
От: σ  
Дата: 28.01.22 17:05
Оценка:
R>ну и флейм от инженера интелла
R>https://lists.qt-project.org/pipermail/development/2018-October/033733.html

>For example, I have ~/src as a bind-mount to ~/dev/src. That means

> ~/src/qt/qt5/qtbase/src/corelib/global/qglobal.h
> ~/dev/src/qt/qt5/qtbase/src/corelib/global/qglobal.h
>are actually the same file, but they aren't for the effects of #pragma once
>because the paths differ.

Ммм, ни капли не выдуманные сетапы в качестве аргументов пошли.

А теперь так:
#define QGLOBAL_H
#include <QtCore/qglobal.h> // ой, гуарды соснули :)
#include <QtCore/qglobal.h>
#undef QGLOBAL_H
#include <QtCore/qglobal.h> // ой, и тут тоже :)
Re[10]: Нужна ли защита от повторного включения
От: AeroSun  
Дата: 28.01.22 18:16
Оценка: +5
Здравствуйте, Андрей Тарасевич, Вы писали:


АТ>За использование голого `#pragma once` — без страховки через include guards — "библиотека с гитхаба" сразу идет ффтопку под взрывы гомерического смеха окружающих. Никому такая библиотека не нужна.



`#pragma once` — это сейчас стандарт де-факто, include guards уже на полпути на свалку истории (вычищаются понемногу из легаси, ибо удобнее и есть уникумы которые умудряются разводить срач о code style как их "правильно" именовать :facepalm.
Де-факто с++ поддерживает это (вся тройка компиляторов уже хрен знает сколько времени, а кто пользуется допотопными — это их личный выбор и личные проблемы, которые остальных не касаются)


АТ>Многие из них, возможно, даже в курсе, что `#pragma once` ничего не дает (по сравнению с include guards), но продолжают механически следовать карго-культу.


Прагма даёт лаконичность, отсутствие необходимости думать как гварды называть + отсутствие срачей о их "правильном" именовании. Взамен этого гварды как раз ничего не дают — они и есть самый явный карго-культ
Re[8]: include guards
От: AeroSun  
Дата: 28.01.22 18:17
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>а существенно более общее и абстрактное понятие.


Это какое?

Хедеры — это как раз самое что ни есть конкретное понятие) Вы наверное с модулями путаете)
Re[9]: include guards
От: σ  
Дата: 29.01.22 15:30
Оценка:
AS>Это какое?

AS>Хедеры — это как раз самое что ни есть конкретное понятие) Вы наверное с модулями путаете)


https://timsong-cpp.github.io/cppwp/n4868/headers#def:header
https://timsong-cpp.github.io/cppwp/n4868/headers#footnote-169
Re[9]: include guards
От: Андрей Тарасевич Беларусь  
Дата: 30.01.22 07:32
Оценка:
Здравствуйте, AeroSun, Вы писали:

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


АТ>>а существенно более общее и абстрактное понятие.


AS>Это какое?


AS>Хедеры — это как раз самое что ни есть конкретное понятие) Вы наверное с модулями путаете)


Ну это смотря что называть "конкретным".

Хедер — это некая внутренняя компиляторная сущность неизвестной природы, обозначаемая своим идентификатором. Использование идентификатора этой сущности в `#include <...>` приводит к замене данной директивы на содержимое хедера.

Это как: "конкретно" или нет?
Best regards,
Андрей Тарасевич
Re[10]: include guards
От: AeroSun  
Дата: 30.01.22 09:28
Оценка: -1
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Хедер — это некая внутренняя компиляторная сущность неизвестной природы, обозначаемая своим идентификатором. Использование идентификатора этой сущности в `#include <...>` приводит к замене данной директивы на содержимое хедера.


Да нет же.
Всё там известно и ясно любому кто хоть немного программировал на С++.
Вот вам задачка на опровержение: предоставьте рабочий пример с идентификатором этой сущности, а не используя адрес файла
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.