2013-03-11 3 views
3

Я использую стороннее приложение с открытым исходным кодом, которое делает что-то, что мне кажется странным. Я хотел бы услышать ваше мнение о том, считаете ли вы, что это неправильно/зло/мерзость/т. Д., Или если есть какая-то оправданная причина для этого.Использование #include для включения разделов кода

Проще говоря, они используют #include pre-proc директивы для включения «заголовочных файлов», которые содержат фрагменты кода. Не прототипы функций. Не встроенные функции. Просто разделы кода.

Вот простой пример. Сначала main.cpp файл:

#include <iostream> 
//Other "normal" includes here... 

int main(int argc, char *argv[]) { 

    cout << "Initializing program..." << endl; 
    #include "parseArgs.h" 

    // ... remainder of the program 

    cout << "Exiting." << endl; 
    return 0; 
} 

И в файле заголовка parseArgs.h, небольшой фрагмент кода. Обратите внимание, что это точно и только то, что находится в файле parseArgs.h. Это не является частью функции. Там нет включают охрану, только следующие 4 строки:

argList args(argc, argv); 
if(!args.valid()) { 
    cout << "Invalid arguments."; 
    exit(1); 
} 

В реальной программе, есть несколько из этих #include директив, с каждым из них делает еще одну небольшую задачу.

Это кажется опасным и сумасшедшим. Я не знаю, почему они не пишут и называют их функциями.

Ваши идеи и мнения?

Thanks, Maddie.

+0

Я не думаю, что это особенно опасно, но звучит безумно и труднее поддерживать. –

+2

Я бы не рекомендовал его, так как он делает код трудным для отслеживания и поддержки, но в этом нет ничего технически. –

+0

Обычно люди используют функции и подобные вещи для повторного использования кода ... – PlasmaHH

ответ

2

Я думаю, вы говорите о OpenFOAM здесь. Проблема, которую эти фрагменты кода решают, заключается в том, чтобы избежать дублирования кода шаблона, который требуется многим приложениям в OpenFOAM.Помещение этого кода в функцию не решит проблему, потому что переменные, объявленные внутри функции, являются локальными для своей области. Можно было бы придумать схему базовых классов, которые содержат эти переменные в качестве членов. Но это просто добавит еще один слой косвенности, который на самом деле ничего не решает. Вы все еще зависите от имен переменных (или, если хотите очистить их, имена получателей).

Лично я не знаю, хорошо ли это или плохо. Так оно и есть, и это часть культуры кода OpenFOAM (если вы хотите) местный lingo. На первый взгляд это удивительно, но к нему привыкнуть довольно быстро.

Однако, если вы не разрабатываете приложения/расширения OpenFOAM самостоятельно, я бы сильно отговорил эту практику. OpenFOAM несколько уникален тем, что содержит практически сотни исполняемых файлов, для которых требуется некоторый перекрывающий шаблонный код, который будет трудно поддерживать в противном случае. Если вы не в такой ситуации, не делайте этого.

+0

встроенные функции решают эти проблемы, более идиоматичны и безопасны. –

+0

Нет, они этого не делают. Если вы примете пример, предоставленный OP, то недостающая вещь состоит в том, что переменная 'args', объявленная фрагментом, будет использоваться разрешенной частью. Встроенная функция не дает вам этого. И, как я уже сказал, это часть специфического для домена * языка OpenFOAM. Я бы настоятельно рекомендовал делать это за пределами OpenFOAM. –

+0

Confused ... 'inline argList make_args (int argc, char * argv []) {return argList args (argc, argv); } '; добавьте проверку ошибок для производственного кода. –

0

Я бы сговорился назвать это «сумасшедшим», так как могут быть причины для этого типа использования #include. Проблема заключается в том, чтобы понять эти причины и судить, является ли это наилучшим подходом в данном контексте. По причине I может Представьте, что код сгенерирован каким-то образом вместо того, чтобы быть рукописным.

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

0

Я думаю, что это очень грязно, и вам лучше написать функцию.

Вот вопрос, который я нашел на SO просит "Why it's valid to include a header file twice in c++?" Вы можете найти ответы на интересующих, я никогда бы не написать свой код таким образом, как я считаю, что исправление ошибок и любые другие проблемы, будут болезненными и длительный

0

Я бы не назвал это «сумасшедшим» - я бы использовал термины «необычный», «трудно понять», «неожиданно» и, следовательно, «трудно читать, отлаживать и поддерживать». Или просто «WTF» - decreasing code quality.

Никогда этого не делайте. Используйте функции. Или, если это действительно так, должно быть, использовать макрос, который делает то же самое, но где люди более знакомы. Да, макросы плохие и могут стать лавашью, когда дело доходит до отладки. Но это хуже.

Редактировать: чтобы уточнить: мне не нравятся макросы. Я избегаю их, где это возможно. В основном. Используйте функции, шаблоны, что угодно. Но когда дело доходит до «макроса или WTF-#include», используйте макрос.

+0

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

+0

Да, я это знаю. Я это написал. Отладка макросов - не забава. Таким образом, использование '# include', возможно, проще отлаживать, чем макросы, но так же хорошо, как и получается. Это гораздо более запутывает, чем макросы. Это хуже, чем макросы * во всех аспектах, кроме отладки *. –