Ops>>2-й: MSVC #pragma once помогает очень хорошо, лечит кривые зависимости, жутко вредит мультиплатформенности.
D>#pragma once мощнее include guards?
D>инклуд гвардия не против циклических зависимостей; многократные включения часто получаются без всяких циклов.
Ступил, конечно же не мощнее. Однако, наверное она что-то дает, может ускоряет компиляцию, зачем-то же в бусте ее используют.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Ops, Вы писали:
Ops>А что не так? Если где-то встречается цикл, то это вполне локализуется, и вполне можно разорвать его, немного подумав. Еще вариант — некоторые компиляторы позволяют насильно внедрять во все юниты какой-нибудь хидер типа StdAfx, возможно он позволяет порвать зависимости.
Т.е. возможно, проект изначально собирался с таким внедренным файлом, а когда его не стало — собираться перестал.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Ops, Вы писали:
Ops>А что не так? Если где-то встречается цикл, то это вполне локализуется, и вполне можно разорвать его, немного подумав. Еще вариант — некоторые компиляторы позволяют насильно внедрять во все юниты какой-нибудь хидер типа StdAfx, возможно он позволяет порвать зависимости.
Отвечу за топикстартера: "не так" то, что цикл надо сперва локализовать, и проблема именно в этом.
Когда файлов много и инклуды макаронные, поиск цикла глазами становится крайне мучителен.
Тем более, что инклуд-гарды маскируют его. И программа становится крайне чувствительной к порядку включения файлов, — возникают гейзенбаги и шрёдинбаги. Особенно, если порядок включения управляется условной компиляцией (кроссплатформенные проекты или просто хитрая дебажная версия).
А уж что делать с обнаруженным циклом — это всё просто и понятно.
Здравствуйте, Ops, Вы писали:
Ops>>>2-й: MSVC #pragma once помогает очень хорошо, лечит кривые зависимости, жутко вредит мультиплатформенности.
D>>#pragma once мощнее include guards?
D>>инклуд гвардия не против циклических зависимостей; многократные включения часто получаются без всяких циклов.
Ops>Ступил, конечно же не мощнее. Однако, наверное она что-то дает, может ускоряет компиляцию, зачем-то же в бусте ее используют.
#pragma once эквивалентна правильно написанному инклуд-гарду.
Выгода от неё в том, что компилятор обрабатывает её быстрее: встретив повторное #include "something.h", он не будет читать файл. Тогда как для инклуд-гарда он, теоретически, должен его прочитать и пройтись по всем этим #ifndef-#endif.
Хорошо, если компилятор умный и распознаёт инклуд-гард в отличие от прочих ветвлений.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Ops, Вы писали:
Ops>>А что не так? Если где-то встречается цикл, то это вполне локализуется, и вполне можно разорвать его, немного подумав. Еще вариант — некоторые компиляторы позволяют насильно внедрять во все юниты какой-нибудь хидер типа StdAfx, возможно он позволяет порвать зависимости.
К>Отвечу за топикстартера: "не так" то, что цикл надо сперва локализовать, и проблема именно в этом.
К>Когда файлов много и инклуды макаронные, поиск цикла глазами становится крайне мучителен. К>Тем более, что инклуд-гарды маскируют его. И программа становится крайне чувствительной к порядку включения файлов, — возникают гейзенбаги и шрёдинбаги. Особенно, если порядок включения управляется условной компиляцией (кроссплатформенные проекты или просто хитрая дебажная версия).
К>А уж что делать с обнаруженным циклом — это всё просто и понятно.
Я плохо представляю себе проект, который не собирался у его автора именно из-за циклов. И сомневаюсь, что ТС вместе с исходниками не достался Makefile (в котором есть все define для компиляции) или что-то подобное.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Vladimir35, Вы писали:
M>>хотелось бы выработать некую технику для упрощения работы.
V>Загружаете утилиту Include File Dependencies Watcher. V>Натравливаете ее на исходные файлы вашего проекта. Получаете график включения файлов. V>Находите визуально циклы в этом графе. V>Находите в цикле хэдер, который использует только ссылки и указатели. V>Переносите из этого хэдера инклюды, вызывающие циклы в cpp файл. V>Добавляете форвард декларации для убранных инклюдов. V>Все.
Респект. Только 1 вопрос, как эта утилита распознаеет разную условную компиляцию?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
К>#pragma once эквивалентна правильно написанному инклуд-гарду.
ещё одно преимущество состоит в том, что не надо выдумывать уникальный идентификатор для инклуд-гарда
К>Выгода от неё в том, что компилятор обрабатывает её быстрее: встретив повторное #include "something.h", он не будет читать файл. Тогда как для инклуд-гарда он, теоретически, должен его прочитать и пройтись по всем этим #ifndef-#endif. К>Хорошо, если компилятор умный и распознаёт инклуд-гард в отличие от прочих ветвлений.
M>gcc уж точно #pragma once поддерживает лет сто. если оно имеется ввиду под кроссплатформенностью.
не совсем так было (хотя, сейчас, начиная с версии 3.4 выдаётся только ворнинг):
However, this high-level handling cuts both ways; the programmer must rely on the compiler to handle #pragma once correctly. If the compiler makes a mistake, for example by failing to recognize that two symbolic links with different names point to the same file, then the compilation will fail. Compilers with #pragma once-related bugs included LCC-Win32 as of 2004 [2][3] and GCC as of 1998.[4] GCC originally gave a warning declaring #pragma once "obsolete" when compiling code that used it. However, with the 3.4 release of GCC, the #pragma once handling code was fixed to behave correctly with symbolic and hard links. The feature was "un-deprecated" and the warning removed.
В>ещё одно преимущество состоит в том, что не надо выдумывать уникальный идентификатор для инклуд-гарда
дело в том что предотвращение двойного включения (которое регулярно получается из-за ромбовидного включения) это не только вопрос оптимизации, это вопрос mere корректности -- в С++ нельзя дважды определить одну структуру. Поэтому правильно всегда делать include guard -- возможно в дополнение к #pragma once, но никак не #pragma once саму по себе -- нужно придерживаться принципа -- если прагму убрать то останется корректный код -- если #pragma once стоит одна, без include guard'ов то это не выполняется.
В>>ещё одно преимущество состоит в том, что не надо выдумывать уникальный идентификатор для инклуд-гарда
D>дело в том что предотвращение двойного включения (которое регулярно получается из-за ромбовидного включения) это не только вопрос оптимизации, это вопрос mere корректности -- в С++ нельзя дважды определить одну структуру. Поэтому правильно всегда делать include guard -- возможно в дополнение к #pragma once, но никак не #pragma once саму по себе -- нужно придерживаться принципа -- если прагму убрать то останется корректный код -- если #pragma once стоит одна, без include guard'ов то это не выполняется.
Зачем? Чтобы больше кода руками писать? Типа настоящие профи вместо одной #pragma once пишут 3 гораздо более длинных строки для вздръжнеэквивалентного эффекта?
D>>дело в том что предотвращение двойного включения (которое регулярно получается из-за ромбовидного включения) это не только вопрос оптимизации, это вопрос mere корректности -- в С++ нельзя дважды определить одну структуру. Поэтому правильно всегда делать include guard -- возможно в дополнение к #pragma once, но никак не #pragma once саму по себе -- нужно придерживаться принципа -- если прагму убрать то останется корректный код -- если #pragma once стоит одна, без include guard'ов то это не выполняется. П>Зачем? Чтобы больше кода руками писать? Типа настоящие профи вместо одной #pragma once пишут 3 гораздо более длинных строки для вздръжнеэквивалентного эффекта?
факт 1: прагмы не обязаны пониматься всеми компиляторами.
факт 2: если компилятор не понимает прагму он ее игнорирует.
факт 3: если проигнорировать #pragma once то в большинстве случаев результатом будет вовсе не увеличившееся время компиляции, результатом будет некорректный код.
D>>>дело в том что предотвращение двойного включения (которое регулярно получается из-за ромбовидного включения) это не только вопрос оптимизации, это вопрос mere корректности -- в С++ нельзя дважды определить одну структуру. Поэтому правильно всегда делать include guard -- возможно в дополнение к #pragma once, но никак не #pragma once саму по себе -- нужно придерживаться принципа -- если прагму убрать то останется корректный код -- если #pragma once стоит одна, без include guard'ов то это не выполняется. П>>Зачем? Чтобы больше кода руками писать? Типа настоящие профи вместо одной #pragma once пишут 3 гораздо более длинных строки для вздръжнеэквивалентного эффекта?
D>факт 1: прагмы не обязаны пониматься всеми компиляторами. D>факт 2: если компилятор не понимает прагму он ее игнорирует. D>факт 3: если проигнорировать #pragma once то в большинстве случаев результатом будет вовсе не увеличившееся время компиляции, результатом будет некорректный код.
GCC 4.x понимает. Студия понимает. Если действительно используется кривой компилятор и нет денег на нормальный, то да, пишите руками guard-ы. Но в 99% случаев это не нужно.
П>GCC 4.x понимает. Студия понимает. Если действительно используется кривой компилятор и нет денег на нормальный, то да, пишите руками guard-ы. Но в 99% случаев это не нужно.
назвать компилятор, удовлетворяющий стандарту, кривым?? ну-ну
П>>GCC 4.x понимает. Студия понимает. Если действительно используется кривой компилятор и нет денег на нормальный, то да, пишите руками guard-ы. Но в 99% случаев это не нужно.
D>назвать компилятор, удовлетворяющий стандарту, кривым?? ну-ну
Да, блин. Стандарты де-юро ползут гораздо медленнее стандартов де-факто. Так можно загнать себя в рамки С89, ибо "самый проверенный" и рефлексировать на него.
D>не ставя гард, ты пишешь ill-formed код
Я решаю конкретные задачи, используя конкретный инструментарий, и получаю за это конкретные деньги. Если я могу решить ту же задачу и получить тот же баблос, затратив меньшее время/усилия, вертел я на шпинделе абстрактные рассуждения про кошерность кода.
П>Да, блин. Стандарты де-юро ползут гораздо медленнее стандартов де-факто. Так можно загнать себя в рамки С89, ибо "самый проверенный" и рефлексировать на него.
Это *прагма*
Прагмы изначально дизайнились так, чтобы их можно было проигнорировать.
Никакая конкретная прагма никогда не может войти в стандарт, потому что прагмы by-design можно игнорировать.
Здравствуйте, пыщьх, Вы писали:
П>Зачем? Чтобы больше кода руками писать? Типа настоящие профи вместо одной #pragma once пишут 3 гораздо более длинных строки для вздръжнеэквивалентного эффекта?
У меня есть скриптик в среде, который спрашивает, как будет зваться новый файл и сразу пишет шапку хедера и cpp'шника в правильно названные файлы, лежащие в нужных папках + добавляет их в проект...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, dilmah, Вы писали: D>факт 1: прагмы не обязаны пониматься всеми компиляторами. D>факт 2: если компилятор не понимает прагму он ее игнорирует. D>факт 3: если проигнорировать #pragma once то в большинстве случаев результатом будет вовсе не увеличившееся время компиляции, результатом будет некорректный код.
Факт 4: Есть компиляторы, например CodeWarrior от MetroWerks, которые интерпретируют эту прагму иначе, чем gcc или M$...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском