Здравствуйте, XJess, Вы писали:
XJ>Привет всем! XJ>Собственно, сабж. Я вот недавно наткнулась в чужом коде на такое. Хотелось бы узнать, зачем человек мог так сделать? Это типа, чтобы включалось как можно ближе к месту использования чего-то из этого хедера?
XJ>Какие грабли могут быть от такого?
XJ>Кстати, по правилам хорошего тона все #include должны ведь быть в начале?
Помимо X-Macros, упомянутых dilmah, я знаю две идиомы использующие include в середине файла:
1) Вставка пакета данных:
int magic_numbers [] = {
#include"magic_numbers.txt"// файл содержит числа через запятую. Как правило, генерируемых.
};
2) Отделение декларации от реализации в случае развесистых шаблонных классов:
// A.h#ifndef A_H_INCLUDED
#define A_H_INCLUDED
template<class A, class B, class C>
class N
{
void f1();
void f2();
void f3();
...
}
#include"A.impl"#endif
// A.impl, используется в роли A.cpp #ifndef A_H_INCLUDED
#error you must include "A.h", but not "A.impl"#endif
template<class A, class B, class C>
void N::f1()
{
...
}
...
Здравствуйте, XJess, Вы писали:
XJ>Собственно, сабж. Я вот недавно наткнулась в чужом коде на такое. Хотелось бы узнать, зачем человек мог так сделать? Это типа, чтобы включалось как можно ближе к месту использования чего-то из этого хедера?
если я использую что-то прямо-тут, то и разумно включить тутже- чтобы не мотать на начало файла.
XJ>Какие грабли могут быть от такого?
гипотетические можно придумать какие-то, но эти грабли будут исключительно субьективными для обьекта который их придумает.
XJ>Кстати, по правилам хорошего тона все #include должны ведь быть в начале?
Здравствуйте, XJess, Вы писали:
XJ>Привет всем! XJ>Собственно, сабж. Я вот недавно наткнулась в чужом коде на такое. Хотелось бы узнать, зачем человек мог так сделать? Это типа, чтобы включалось как можно ближе к месту использования чего-то из этого хедера?
XJ>Какие грабли могут быть от такого?
XJ>Кстати, по правилам хорошего тона все #include должны ведь быть в начале?
если не используется всякая препроцессорная магия — все инклуды должны быть в начале, чтобы вносить зависимости.
А если используется — тут возможны моря вариантов, хотя я лично предпочитаю Boost.Preprocessor и прибегаю к таким вот включениям огрызков файлов в середине только если огрызки слишком большие.
Здравствуйте, MasterZiv, Вы писали:
MZ>Аааа, вот они, повылазили. MZ>Лентяи и раздолбаи. MZ>Моё мнение по этому поводу -- лень мотать -- иди работай грузчиком.
а я безработный, и да я ленивый.
>> XJ>Кстати, по правилам хорошего тона все #include должны ведь быть в начале? >> >> нет, с чего вдруг?
MZ>С того, чтобы открыв исходник, сразу видеть от чего он зависит.
всё просто и понятно- и в одном месте, и помоему совсем твердолобым нужно быть, чтобы #include <signal.h> выносить в начало файла.
MZ>Заметь, это не правила С++ или С, а хорошего тона. В общем это MZ>правила типа "не делай другим того, чего ты не хотел бы чтобы
вы вбили себе что-то в голову(типа goto плохо, инклуды посреди файла плохо и т.п), и свято этому верите- как правило это от скудоумия(легче вбить барану в голову- "не убий", "не укради" чем заставить думать и научить оценивать риски и возможную выгоду от своих потонциальных действий для себя и социума).
Привет всем!
Собственно, сабж. Я вот недавно наткнулась в чужом коде на такое. Хотелось бы узнать, зачем человек мог так сделать? Это типа, чтобы включалось как можно ближе к месту использования чего-то из этого хедера?
Какие грабли могут быть от такого?
Кстати, по правилам хорошего тона все #include должны ведь быть в начале?
Здравствуйте, XJess, Вы писали:
XJ>Привет всем! XJ>Собственно, сабж. Я вот недавно наткнулась в чужом коде на такое. Хотелось бы узнать, зачем человек мог так сделать? Это типа, чтобы включалось как можно ближе к месту использования чего-то из этого хедера?
XJ>Какие грабли могут быть от такого?
XJ>Кстати, по правилам хорошего тона все #include должны ведь быть в начале?
Когда все include собраны в одном месте, легче найти это место и увидеть все зависимости. Грабли могут быть если, например, кто-нибудь захочет добавить using namespace blah-blah и не заметит, что где-то ниже по коду стоят директивы include. Если человек делает это, потому что ему лень прокручивать файл в начало и обратно, научите его комбинациям "Ctrl+Home" и "Ctrl+-" (для MSVS).
Здравствуйте, XJess, Вы писали:
XJ>Собственно, сабж. Я вот недавно наткнулась в чужом коде на такое. Хотелось бы узнать, зачем человек мог так сделать? Это типа, чтобы включалось как можно ближе к месту использования чего-то из этого хедера?
XJ>Какие грабли могут быть от такого?
Про грабли уже написали, напишу, для чего можно использовать.
Например, чтобы вынести реализацию inline функций в отдельный файл. У этого файла не будет scope guard'ов, расширение будет другим (например, .inl) и подключаться он будет после объявления класса.
Причина — в нескольких файлах небольшого размера легче ориентироваться, чем в одном километровом. А компилятору пофигу.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, XJess, Вы писали:
XJ>Привет всем! XJ>Собственно, сабж. Я вот недавно наткнулась в чужом коде на такое. Хотелось бы узнать, зачем человек мог так сделать?
Обычно так не делают.
Но раз человек так сделал, то у него наверное были причины.
Попробуй спроси у него лично.
Или он физически не доступен?
Здравствуйте, XJess, Вы писали:
XJ>Собственно, сабж. Я вот недавно наткнулась в чужом коде на такое. Хотелось бы узнать, зачем человек мог так сделать? Это типа, чтобы включалось как можно ближе к месту использования чего-то из этого хедера?
Иногда бывает нужно что-нибудь по-быстренькому попробовать, не хватает какого-нибудь #include, и втыкаешь его прям по месту использования (чтобы к верху файла не тянуться). Потом, если изменение останется в коде, можно случайно забыть перенести #include в положенное для него место.
XJ>Какие грабли могут быть от такого?
Если этим злоупотреблять, можно приобрести репутацию быдлокодера
Кроме того, если у вас случайно возникнет конфликт между вашим кодом и хидером (например, вы случайно использовали имя макроса или функции, которую использует этот хидер), то если #include стоит в середине файла, ошибка может вылезти не в вашем коде, а в хидере, и вы охренеете от разглядывания его
XJ>Кстати, по правилам хорошего тона все #include должны ведь быть в начале?
Да. Язык это не энфорсит, но принято ставить #include в начале.
Sni4ok wrote:
> если я использую что-то прямо-тут, то и разумно включить тутже- чтобы не > мотать на начало файла.
Аааа, вот они, повылазили.
Лентяи и раздолбаи.
Моё мнение по этому поводу -- лень мотать -- иди работай грузчиком.
> XJ>Какие грабли могут быть от такого? > > гипотетические можно придумать какие-то, но эти грабли будут > исключительно субьективными для обьекта который их придумает.
см. мой пост в теме.
> XJ>Кстати, по правилам хорошего тона все #include должны ведь быть в начале? > > нет, с чего вдруг?
С того, чтобы открыв исходник, сразу видеть от чего он зависит.
Заметь, это не правила С++ или С, а хорошего тона. В общем это
правила типа "не делай другим того, чего ты не хотел бы чтобы
сделали себе". Оноже "не гадь где еш".
Здравствуйте, MasterZiv, Вы писали:
>> если я использую что-то прямо-тут, то и разумно включить тутже- чтобы не >> мотать на начало файла.
MZ>Аааа, вот они, повылазили. MZ>Лентяи и раздолбаи. MZ>Моё мнение по этому поводу -- лень мотать -- иди работай грузчиком.
Лень — двигатель прогресса и враг копипасты
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Здравствуйте, MasterZiv, Вы писали:
MZ>С того, чтобы открыв исходник, сразу видеть от чего он зависит. MZ>Заметь, это не правила С++ или С, а хорошего тона. В общем это MZ>правила типа "не делай другим того, чего ты не хотел бы чтобы MZ>сделали себе". Оноже "не гадь где еш".
"Ешь" пишется с мягким знаком на конце. И не делать этого — все равно, как #include посреди файла писать
В библиотеках на С можно часто встретить, также в исходниках FreeBSD часто встречал:
// somedata.inc
0x87677457 0x45638767
0x45763565 0x14653575
... // и т.д.
// someheader.h
const int v[256] = {
#include somedata.inc
};
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
S>В библиотеках на С можно часто встретить, также в исходниках FreeBSD часто встречал:
S>// somedata.inc S>0x87677457 0x45638767 S>0x45763565 0x14653575 S>... // и т.д.
S>// someheader.h S>const int v[256] = { S>#include somedata.inc S>};
это особенно оправданно, когда такой .inc файл автогенерируется скриптом.
// somedata.inc
0x87677457, 0x45638767,
0x45763565, 0x14653575,
... // и т.д.
// someheader.hconst int v[256] = {
#include somedata.inc
};
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Sni4ok wrote:
> вы вбили себе что-то в голову(типа goto плохо, инклуды посреди файла > плохо и т.п),
Я ничего не вбивал. Это -- опыт. Сын ошибок трудных.
Выгоды от непомещения #include наверх файла никакой.
Польза есть -- хорошо оформлен код. Понятие
"код хорошо оформлен" к сожалению сложное и многогранное.
Я не смогу сейчас объяснить его преимущества.
MZ>Я ничего не вбивал. Это -- опыт. Сын ошибок трудных. MZ>Выгоды от непомещения #include наверх файла никакой.
возможно, что выгоды нет никакой, если инклуд ставят просто рядом с местом использования. Я никогда так не делал, и не страдал.
Но выше привели ряд приемов, которые полезны, и при которых используется включение инклудов не в начало.
(1) .inl хедеры, в которых пишут определения инлайновых функций, либо шаблонных функций, методов шаблонных классов. Их обычно включают в конец соответствующего хедера. Это регулярный прием. Их выделяют в отдельные файлы, потому что физически они должны быть вместе с .h файлом, но логичски они больше похожи на .cc файлы. Инклудят их в конец чтобы было после определений нужных классов/структур.
(2) Автогенерированные данные. Скрипт генерирует файл с колонкой чисел, далее этот файл включается непосредственно в том месте где определяется соответствующий массив. Если здесь придерживаться помещения #include только в начало, то тогда скрипту придется генерировать не только колонку цифр, но и весь этот boilerplate необходимый для хедеров -- то есть скрипт начинает заниматься не свои делом, а во вторых знание этого boilerplate приходится помещать в этот скрипт, которому нет никакой нужды про него знать.
(3) X-Macros. Мне неоднократно встречались ситуации, когда есть некий набор связанных сущностей, который можно оформить в виде таблицы. Из этих сущностей нужно слепить код, но при этом зависимости между сущностями размазываются по коду. Универсальное решение -- это использовать кодогенерацию, но это слишком мощное решение, и во многих случаях достаточно препроцессора и X-Macros приема.
Самый простой пример использования -- у тебя есть enum и соответсвенно набор констант, и есть набор каких-то других вещей, скажем, строк, которые взаимно однозначно соответствуют каждой константе из энума. С техникой X-Macros все красиво -- ты оформляешь один файл с таблицей соответствия константа<->строка, и дальше манипулируешь им. Если это не делать, то константы и их соответсвия размазываются и дублируются по коду.
Здравствуйте, MasterZiv, Вы писали:
MZ>Поучи бабушку щи варить лучше. MZ>Мягкий знак пишется на конце глаголов в неопределённой форме. MZ>Тут — второе лицо, единственное число.
Здравствуйте, frogkiller, Вы писали:
MZ>>Аааа, вот они, повылазили. MZ>>Лентяи и раздолбаи. MZ>>Моё мнение по этому поводу -- лень мотать -- иди работай грузчиком.
F>Лень — двигатель прогресса и враг копипасты
копипаст обычно от лени и добавляют, т.к. не охото тратить время на нормальное решение.
Здравствуйте, Олег К., Вы писали:
ОК>Отношусь отрицательно но советую смириться. Это избытки нашей профессии.
ОК>Со мной сейчас работает товарищ. Так ему если нужна константа в середине функции, то он вместо того чтобы написать ОК>