народ на реддите в +100500 раз устроил флейм по поводу include guards link
вообщем то я не поклонник секты pragma once
но в конце прошлого года на одном из собесов чуть чуть пофлудил
а сейчас решил все таки проверить
итог
пару пет проектов
git ls-files | xargs wc -l
один проект-ик
107820 total
другой проект-ик
87018 total
тестировал под виндой на msvc последним из 19
с изначальным
#ifndef _file_hpp_
#define _file_hpp_
...
#endif
и дополненными
#ifndef _file_hpp_
#define _file_hpp_
#pragma once
...
#endif
результаты не впечатлили
первый
без pragma once — 5.48 минуты
c pragma once — 4.45 минут
второй
без pragma once — 3.41 минут
c pragma once — 3.8 минут
вообщем в пределах погрешности
я бы сказал разницы особой нет
итого
не смотря на то что писанины с pragma once меньше
нарваться на проблемы с одинаковыми файлами по разным путям — больше
останусь на старом добром ifndef
Здравствуйте, reversecode, Вы писали:
R>народ на реддите в +100500 раз устроил флейм по поводу include guards
R>итого R>не смотря на то что писанины с pragma once меньше R>нарваться на проблемы с одинаковыми файлами по разным путям — больше R>останусь на старом добром ifndef
А что не так с прагма уанс, можно вкратце, и почему это секта?
Здравствуйте, reversecode, Вы писали:
R>останусь на старом добром ifndef
Я тоже использую страж включения, но тут нужно сразу решить, или используешь только страж включения, или только pragma once.
А ещё есть другие мысли по этому поводу. Обязательны ли эти конструкции в принципе? Что будет, если их не писать? Очевидно компилятор заругается при повторном включении, но... в случае использования защитных конструкций от повторного включения даём добро на многократные повторные включения.
Вот и ответь мне username, нужны ли стражи включения в своём личном проекте?
Может мы тут все дураки и не лечимся. Пихаем множество включений зная, что они будут проигнорированы благодаря стражу включения. А кто потом будет удалять лишние включения #inlcude? Да, никто и не будет, ведь всё и так работает.
Говорят Объектно-ориентированное программирование — катастрофа на триллион долларов, а что если стражи включения это катастрофа на триллион долларов. Из-за этих уродских макроконструкций код C/C++ становится уродливым, отвлекает программистов на его написание. Бьерн Страуструп вообще-то ратовал за исключение макросов из обихода, но стражи включения как-то пролезли даже в его идеологию.
или или
вы в стандартные хидеры M$ хоть раз смотрели ?
там и pragma once и include guards
собственно мне pragma once был любопытен с точки зрения ускорения компиляции
но после тестовых замеров
и раздумий
мне она ничего не сможет ускорить
поскольку пет проекты все мои
и что куда и зачем я инклудю, я прекрасно контролирую сам
и повторных переинклудов у меня нет
и еще я пришел к выводу что это хороший критерий оценки команды программистов которые работают над одним проектом
если использовался include guard
и в проект добавили еще и pragma once и скорость компиляции возросла
значит программисты которые работают над проектом
слабо представляют дерево зависимости и включают хидеры на глаз не понимая нужно или не нужно
типичный пример недавняя новость про ускорение компиляции линукс ядра после переоптимизации подключения хидеров
меня это посмешило
господа линукс программисты явно не в курсе про pragma once
без переоптимизаций инклудов
банальной pragma once они бы добились тех же самых ускорений при сборке ядра
Здравствуйте, reversecode, Вы писали:
R>или или R>вы в стандартные хидеры M$ хоть раз смотрели ? R>там и pragma once и include guards
А я так и делал вначале, а потом понял, что это крайне глупо. Впрочем я давно уже ушёл от инструментов майков, таких как "вижуал студио". Мне на скорость компиляции класть с высокой колокольни. Эта проблема решается многоядерной компиляцией и покупкой компьютера с более производительным процессором. И то, проект должен быть гигантским, чтобы нужно было такое делать. Но на код я смотрю самолично, а это уже другой разговор.
Да и в целом, я что обезьяна копировать за майками. Например, пихать везде stdafx.h. Нет, если используешь страж включения, то pragma once не нужен. И наоборот, начал пользоваться pragma once, то зачем городить макроконструкции. Оставайся уж тогда на страже включения из трёх макродиректив (#ifndef, #define, #endif).
R>и еще я пришел к выводу что это хороший критерий оценки команды программистов которые работают над одним проектом
Это совершенно другая тема. Мне сейчас не хочется играть в политкорректность, если наниматели используют что-то такое для оценки команды, то они дебилы. Всё же просто, для проекта должны быть правила оформления кода. Сказали писать страж включения, пишешь страж включения. Сказали писать pragma once, пишешь pragma once. Сказали делать и то и другое, делаешь и то и другое. А кто-то может не писать ничего и это будет задокументировано как обязательный стиль для проекта. А если начинаются споры, ну так и пусть катятся эти наниматели колбаской, ищут себе "единомышленников". Если для них главное идеология, а не единый прописанный в правилах проекта стиль кода.
R>меня это посмешило R>господа линукс программисты явно не в курсе про pragma once R>без переоптимизаций инклудов R>банальной pragma once они бы добились тех же самых ускорений при сборке ядра
А кто такие линукс программисты? Те кто делают ядро линукса? Те кто используют системные вызовы линукса? Те кто просто программируют под линуксом? Я как человек постоянно сидящий в Debian, причём по большей части использую его как мультимедийную развлекательную платформу для всего, веб-серфинг, фильмы, игры и так далее, скажу так, мне насрать на оптимизации. А если говорить о сборщиках ядра, ну так это их проект и их дело. В проекте логично следовать принятым соглашениям чтобы код был в едином стиле.
Но вопрос остаётся открытым, а везде ли и всегда нужны конструкции предотвращающие ошибки компилятора при повторном включении?
Представь, что придёт богатый наниматель и скажет, что никаких стражей включения и pragma once быть в его проекте не должно. Что дескать нефиг включать, когда можно не включать. Всё должно быть супер продумано, а не состоять из заплат. Или другое требование, весь проект должен быть в одном файле. А почему бы и нет. Конечно, кто-то скажет, что я сейчас выдумываю, но неудобная правда в том, что стандарта, как обязательно надо, и как обязательно не надо, нет.
R>#ifndef _file_hpp_
R>#define _file_hpp_
R>#pragma once
R>...
R>#endif
R>
R>результаты не впечатлили
Компиляторы, которые оптимизируют #pragma once лучше, чем include guards, делают это тогда, когда #pragma once идёт первой, до неё только, возможно, комментарии и пустые строки.
Но вроде как сейчас компиляторов, оптимизирующих #pragma once лучше — нет. Ранее был таковым MSVC.
М>>А что не так с прагма уанс, можно вкратце, и почему это секта?
R>/somedir1/header_file.h R>/somedir2/header_file.h
R>два хидеры с разным содержанием но одинаковым именем R>включенные в один модуль R>считается что при прагма онце будут проблемы
М>>А что не так с прагма уанс, можно вкратце, и почему это секта?
R>/somedir1/header_file.h R>/somedir2/header_file.h
R>два хидеры с разным содержанием но одинаковым именем R>включенные в один модуль R>считается что при прагма онце будут проблемы
Нет, проблема как раз противоположная. Когда один и тот же файл лежит и включается из разных мест (да такое бывает в реальных проектах) и тогда в случае прагмы эти файлы будут считаться разными и естественно каждый раз включаться заново. А в твоём случае не поможет и ifndef header_file_h. При первом включении header_file.h в таблицу макросов препроцессора будет внесено значение header_file_h и последующие включения header_file.h будут скипнуты. В этом случае как раз и поможет прагма Так что если не знаешь структуры проекта более безопасно писать прагму, но если всё контролируешь, то, конечно, старый добрый ifndef. Единственный минус ifndef — он засирает таблицу макросов ненужной шелухой, но как ты показал сам удар по производительности компиляции незначителен, что в общем не удивительно.
Здравствуйте, YuriV, Вы писали:
YV>Нет, проблема как раз противоположная. Когда один и тот же файл лежит и включается из разных мест (да такое бывает в реальных проектах) и тогда в случае прагмы эти файлы будут считаться разными и естественно каждый раз включаться заново. А в твоём случае не поможет и ifdef имя_файла. При первом включении header_file.h в таблицу макросов препроцессора будет внесено значение header_file_h и следующие включение header_file.h будет скипнуто. В этом случае как раз и поможет прагма Так что если не знаешь структуры проекта более безопасно писать прагму, но если всё контролируешь, то конечно старый добрый ifdef. Единственный минус ifdef он засирает таблицу макросов ненужной шелухой, но как ты показал сам удар по производительности компиляции незначителен, что в общем не удивительно.
Ифдеф еще засирает заголовочные файлы лишними отвлекающими строками. Плюс, если вдруг вручную пишешь этот guard (что редко, но мало ли), можешь ошибиться в написании названия.
Вообще не понимаю, почему не сделали pragma once не на основании полного пути файла, а на основании имени файла и, например, хеша содержимого. Тогда уродливые ifdef ушли бы в прошлое.
Здравствуйте, Андрей Тарасевич, Вы писали:
М>>А что не так с прагма уанс, можно вкратце, и почему это секта?
АТ>Ну хотя бы то, что нет никакого "прагма уанс". Это не стандартная фича.
М М>Ифдеф еще засирает заголовочные файлы лишними отвлекающими строками. Плюс, если вдруг вручную пишешь этот guard (что редко, но мало ли), можешь ошибиться в написании названия. М>Вообще не понимаю, почему не сделали pragma once не на основании полного пути файла, а на основании имени файла и, например, хеша содержимого. Тогда уродливые ifdef ушли бы в прошлое.
Откуда дровишки?
Вики пишет:
...То есть, #pragma once применяется для тех же целей, что и include guard, но требует меньше кода и не допускает возможности коллизии имён.
...
Тем не менее, в релизе 3.4 GCC код обработки команды #pragma once был исправлен для корректной работы с символьными и жёсткими ссылками. Данная возможность была сочтена полезной и предупреждение было убрано.
Здравствуйте, velkin, Вы писали:
R>>останусь на старом добром ifndef
V>Я тоже использую страж включения, но тут нужно сразу решить, или используешь только страж включения, или только pragma once.
Я использую и то и то одновременно. А в чем проблема?
Здравствуйте, удусекшл, Вы писали:
V>>Я тоже использую страж включения, но тут нужно сразу решить, или используешь только страж включения, или только pragma once. У>Я использую и то и то одновременно. А в чем проблема?
В pragma once просто нет смысла, если стоит страж включения ifndef-define-endif. Я себя раньше спрашивал, а зачем я прописываю и то и другое. В итоге забил и оставил лишь страж включения. Но это было очень давно, тогда pragma once ещё не стала практически стандартом.
не однозначно
если судить по msvс шным стандартным хидерам, то да pragma once они делают перед include guard
если вчитываться в реддит или сорсы asio networking, то после
но под утро я решил сделать бранч и потестить и перед
по результатам, все равно разницы нет
если следовать логике, то once должна быть после guard
иначе можно промахнуться в случаях когда одно и тоже имя файла
присутствует в разных директориях ну и once будет как всегда впереди
как я сделал выводы выше топиками
из за того что я сам не плохо контроллирую что и куда я инклудю
и лишних включений у меня нет, то это никак не отразится
а вот на проектах где программисты потеряли уже инклуде флов
и инклудят лишних хидеров
им бы once оптимизации явно помогли
Здравствуйте, reversecode, Вы писали:
R>собственно мне pragma once был любопытен с точки зрения ускорения компиляции
С чего бы ему что-то ускорять?
Вот как надо:
Здравствуйте, andyp, Вы писали:
A>Съехал на прагму давно уже. Основные причины — копипаста гардов с одинаковыми именами и убитые при редактировании эндифы в хвосте файла.
+ переиминование файла не требует дополнительных действий.