Продолжая использовать наш сайт, вы даете согласие на обработку файлов cookie, которые обеспечивают правильную работу сайта. Благодаря им мы улучшаем сайт!
Принять и закрыть

Читать, слущать книги онлайн бесплатно!

Электронная Литература.

Бесплатная онлайн библиотека.

Читать: Стандарты программирования на С++. 101 правило и рекомендация - Герб Саттер на бесплатной онлайн библиотеке Э-Лит


Помоги проекту - поделись книгой:

Герб Саттер

Андрей Александреску

Стандарты программирования на С++

101 правило и рекомендация

Миллионам нынешних программистов на C++

Предисловие

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

— Алан Перлис (Alan Perlis) [выделено нами]

Лучшее в стандарте то, что он предоставляет богатый выбор.

— Приписывается разным людям

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

• Стандарты кодирования должны отражать лучший опыт проб и ошибок всего сообщества программистов. В них должны содержаться проверенные идиомы, основанные на опыте и твердом понимании языка. В частности, стандарт кодирования должен основываться на исчерпывающем анализе литературы по разработке программного обеспечения, и объединять воедино правила, рекомендации и наилучшие практические решения, которые в противном случае оказываются разбросанными по многочисленным источникам.

• Природа не терпит пустоты. Если вы не разработаете набор правил, то это сделает кто-то другой. Такие "самопальные" стандарты, как правило, грешат тем, что включают нежелательные для стандарта требования; например, многие из них, по сути, заставляют программистов использовать C++ просто как улучшенный С.

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

Как пользоваться этой книгой

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

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

Эта книга предназначена для того, чтобы послужить основой для вашего стандарта кодирования и быть в той или иной мере включенной в него. Это — не ultima ratio в стандартах кодирования, и ваша группа может разработать (или прибавить) свои правила, в наибольшей степени подходящие для вашей конкретной группы или для конкретной решаемой задачи, так что вы не должны быть скованы этой книгой по рукам и ногам. Тем не менее, мы надеемся, что эта книга поможет вам сберечь время и усилия при разработке собственного стандарта кодирования, а также будет способствовать повышению его качества и последовательности.

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

И наконец, периодически творчески пересматривайте собственные стандарты с учетом практического опыта, приобретенного всей командой при работе над проектом.

Стандарты кодирования и вы

Хорошие стандарты кодирования могут принести немалую выгоду с различных точек зрения.

• Повышение качества кода. Работа в соответствии со стандартом приводит к однотипному решению одинаковых задач, что повышает ясность кода и упрощает его сопровождение.

• Повышение скорости разработки. Разработчику не приходится решать все задачи и принимать решения "с нуля".

• Повышение уровня взаимодействия в команде. Наличие стандарта позволяет уменьшить разногласия в команде и устранить ненужные дебаты по мелким вопросам, облегчает понимание и поддержку чужого кода членами команды.

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

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

У разработчиков программного обеспечения регулярно возникают ситуации, когда что-то надо было сделать еще вчера — на позавчера. Когда на нас давит график работ (который к тому же имеет тенденцию сдвигаться в одном направлении, и то, что по плану должно было заработать завтра, от нас начинают требовать еще вчера...), мы работаем так, как приучены. Неряшливые программисты, которые даже при обычной неспешной работе не помнят о правильных принципах разработки программного обеспечения (а то и вовсе не знакомы с ними), при нехватке времени окажутся еще небрежнее, а их код будет изобиловать ошибками. Соответственно, программист, который выработал в себе хорошие привычки и регулярно ими пользуется, при "повышенном давлении" будет продолжать выдавать качественный код.

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

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

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

Эта книга предназначена для программистов всех уровней.

Если вы начинающий программист — мы надеемся, что рекомендации и их пояснения достаточно поучительны и помогут вам в понимании того, какие стили и идиомы С++ поддерживает наиболее естественным образом. В описании каждого правила и рекомендации приводится краткое обоснование и обсуждение, чтобы вы не просто механически запомнили правило, а поняли его суть.

Для программистов среднего и высокого уровня при описании каждого правила приводится список ссылок, который позволит вам углубленно изучить заинтересовавший вас вопрос, проведя поиск корней правила в системе типов, грамматике и объектной модели С++.

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

Об этой книге

Основными принципами дизайна данной книги являются следующие.

• Краткость — сестра таланта. Чем больше стандарт кодирования по размеру, тем больше шансов, что он будет благополучно проигнорирован. Читают и используют обычно короткие стандарты. Длинные разделы, как правило, просто просматривают "по диагонали", короткие статьи обычно удостаиваются внимательного прочтения.

• Никакой материал не должен вызывать дискуссий. Эта книга документирует широко используемые стандарты, а не изобретает их. Если некоторая рекомендация не применима во всех ситуациях, то мы так и пишем — "подумайте о применении X" вместо "делайте X". Кроме того, к каждому правилу указаны все общепринятые исключения.

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

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

• Например, "не возвращайте указатель/ссылку на локальную переменную" — хороший совет, но он не включен в данную книгу, поскольку практически все компиляторы выдают соответствующее предупреждение, к тому же этот вопрос раскрывается в первом разделе книги.

• Рекомендация "используйте редактор (компилятор, отладчик)" — тоже хороший совет, но, конечно, вы используете эти инструменты и без нашего напоминания. Вместо этого мы рекомендуем использовать автоматизированные системы сборки программ и системы управления версиями.

• Еще один совет — "не злоупотребляйте goto" — исходя из нашего опыта, и так широко известен всем программистам, так что нет смысла повторяться.

Каждый раздел состоит из следующих частей.

• Заглавие. Краткое название раздела, поясняющее, о чем будет идти речь.

• Резюме. Краткое изложение сути вопроса.

• Обсуждение. Расширенное пояснение рекомендации. Зачастую включает краткое обоснование, но учтите, что полную информацию по данному вопросу следует искать в приведенных ссылках.

• Примеры (если таковые имеются). Примеры, демонстрирующие правило или позволяющие лучше его понять и запомнить.

• Исключения (если таковые имеются). Описание ситуаций (обычно редких), когда приведенное правило неприменимо. Однако остерегайтесь попасть в ловушку, думая, что ваш случай особый и что в вашей ситуации это правило неприменимо, — обычно при здравом размышлении оказывается, что ничего особого в вашей ситуации нет и описанное правило может быть с успехом вами применено.

• Ссылки. В приведенной в этом подразделе литературе по С++ вы найдете более полный анализ рассматриваемого в разделе вопроса.

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

Благодарности

Мы от всей души благодарны редактору серии Бьярну Страуструпу (Bjarne Stroustrup), редакторам Питеру Гордону (Peter Gordon) и Дебби Лафферти (Debbie Lafferty), а также Тирреллу Албаху (Tyrrell Albaugh), Ким Бодихаймер (Kim Boedigheimer), Джону Фуллеру (John Fuller), Бернарду Гаффни (Bernard Gaffney), Курту Джонсону (Curt Johnson), Чанде Лири-Коту (Chanda Leary-Coutu), Чарли Ледди (Charles Leddy), Хитеру Муллэйн (Heather Mullane), Чути Прасертсиху (Chuti Prasertsith), Ларе Вайсонг (Lara Wysong) и всем остальным работникам издательства Addison-Wesley, помогавшим нам в нашей работе над этим проектом. Нам было очень приятно работать с ними.

На идею и оформление книги нас натолкнули несколько источников, включая такие, как [Cline99], [Peters99], а также работы легендарного и широко цитируемого Алана Перлиса (Alan Perlis).

Особая благодарность тем людям, чьи отзывы помогли нам сделать многие части книги намного лучшими, чем они были бы без этих замечаний. Особенно большое влияние на книгу оказали острые комментарии Бьярна Страуструпа. Мы очень хотим поблагодарить за активное участие в обсуждении материала и высказанные замечания таких людей, как Дэйв Абрамс (Dave Abrahams), Маршалл Клайн (Marshall Cline), Кевлин Хенни (Kevlin Henney), Говард Хиннант (Howard Hinnant), Джим Хайслоп (Jim Hyslop), Николаи Джосаттис (Nicolai Josuttis), Йон Калб (Jon Kalb), Макс Хесин (Max Khesin), Стен Липпман (Stan Lippman), Скотт Мейерс (Scott Meyers) и Дэвид Вандевурд (Daveed Vandevoorde). Кроме того, отдельное спасибо хотелось бы сказать Чаку Аллисону (Chuck Allison), Самиру Байяю (Samir Bajaj), Марку Барбуру (Marc Barbour), Тревису Брауну (Travis Brown), Нилу Кумбесу (Nil Coombes), Дамиану Дечеву (Damian Dechev), Стиву Дьюхарсту (Steve Dewhurst), Питеру Димову (Peter Dimov), Аттиле Фехеру (Attila Feher), Алану Гриффитсу (Alan Griffiths), Мичи Хеннингу (Michi Henning), Джеймсу Канзе (James Kanze), Бартошу Милевски (Bartosz Milewski), Мэтту Маркусу (Matt Marcus), Балогу Палу (Balog Pal), Владимиру Прусу (Vladimir Prus), Дэну Саксу (Dan Saks), Люку Вагнеру (Luke Wagner), Мэтью Вильсону (Matthew Wilson) и Леору Золману (Leor Zolman).

Как обычно, все оставшиеся в книге ошибки и недосмотры — на нашей совести, а не на их.

Герб Саттер (Herb Sutter) Андрей Александреску (Andrei Alexandrescu) Сиэтл, сентябрь 2004

Вопросы организации и стратегии

Если бы строители строили здания так же, как программисты пишут программы, — то первый же залетевший дятел разрушил бы всю цивилизацию.

— Джеральд Вайнберг (Gerald Weinberg)

Следуя великой традиции С и С++, мы начинаем отсчет с нуля. Главный совет — под номером 0 — говорит о том, что основной советчик по поводу стандартов кодирования — наши чувства и ощущения.

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

В этом разделе книги наиболее важной мы считаем нулевую рекомендацию — "Не мелочитесь, или Что не следует стандартизировать".

0. Не мелочитесь, или Что не следует стандартизировать

Резюме

Скажем кратко: не мелочитесь.

Обсуждение

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

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

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

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

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

• Следует использовать непротиворечивые соглашения об именовании, не слишком мелочно регламентируя его. Имеется только два императивных требования по поводу именования: никогда не используйте имена, начинающиеся с подчеркивания или содержащие двойное подчеркивание, и всегда используйте для макросов только прописные буквы (ONLY_UPPERCASE_NAMES), при этом никогда не применяя в качестве имен макросов обычные слова или сокращения (включая распространенные параметры шаблонов, такие как T или U; запись #define T anything может привести к крупным неприятностям). В остальных случаях используйте непротиворечивые значимые имена и следуйте соглашениям, принятым для данного файла или модуля. (Если вы не можете сами разработать соглашение об именовании, попробуйте воспользоваться следующим: имена классов, функций и перечислений должны выглядеть как LikeThis, имена переменных — likeThis, имена закрытых членов-данных — likeThis_, и имена макросов — LIKE_THIS.)

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

И наконец, не пытайтесь заставлять использовать устаревшие правила (см. примеры 2 и 3), даже если они имеются в старых стандартах кодирования.

Примеры

Пример 1. Размещение фигурных скобок. Нет никакой разницы в плане удобочитаемости следующих фрагментов:

void using k_and_r_style() {

 // ...

}

void putting_each_brace_on_its_own_line()

{

 // ...

}

void or_putting_each_brace_on_its_own_line_indented()

 {

  // ...

 }

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

Пример 2. Пробелы или табуляция. В некоторых командах использование табуляции запрещено (например, [BoostLRG]) на том основании, что размер табуляции варьируется от редактора к редактору, а это приводит к тому, что отступы оказываются слишком малы или слишком велики. В других командах табуляции разрешены. Важно только быть последовательным. Если вы позволяете использовать табуляцию, убедитесь, что такое решение не будет мешать ясности кода и его удобочитаемости, если члены команды будут сопровождать код друг друга (см. руководство 6). Если использование табуляции не разрешено, позвольте редактору преобразовывать пробелы в табуляции при чтении исходного файла, чтобы программисты могли работать с ними в редакторе. Однако убедитесь, что при сохранении файла

Пример 3. Венгерская запись. Запись, при которой информация о типе включается в имя переменной, приносит пользу в языке программирования, небезопасном с точки зрения типов (особенно в С); возможна, хотя и не приносит никакой пользы (только недостатки) в объектно-ориентированных языках; и невозможна в обобщенном программировании. Таким образом, стандарт кодирования С++ не должен требовать использования венгерской записи, более того, может требовать её запрета.

Пример 4. Один вход, один выход (Single entry, single exit — "SESE"). Исторически некоторые стандарты кодирования требуют, чтобы каждая функция имела в точности один выход, что подразумевает одну инструкцию return. Такое требование является устаревшим в языках, поддерживающих исключения и деструкторы, так что функции обычно имеют несколько неявных выходов. Вместо этого стоит следовать стандарту наподобие рекомендации 5, которая требует от функций простоты и краткости, что делает их более простыми для понимания

Ссылки

[BoostLRG] • [Brooks95] §12 • [Constantine95] §29 • [Keffer95] p. 1 • [Kernighan99] §1.1, §1.3, §1.6-7 • [Lakos96] §1.4.1, §2.7 • [McConnell93] §9, §19 • [Stroustrup94] §4.2-3 • [Stroustrup00] §4.9.3, §6.4, §7.8, §С.1 [Sutter00] §6.1, §20 [SuttHysl01]

1. Компилируйте без замечаний при максимальном уровне предупреждений

Резюме

Следует серьезно относиться к предупреждениям компилятора и использовать максимальный уровень вывода предупреждений вашим компилятором. Компиляция должна выполняться без каких-либо предупреждений. Вы должны понимать все выдаваемые предупреждения и устранять их путем изменения кода, а не снижения уровня вывода предупреждений.

Обсуждение

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

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

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

Делайте это всегда — даже если программа выглядит корректно работающей. Делайте это, даже если убедились в мягкости предупреждения. Даже легкие предупреждения могут скрывать последующие предупреждения, указывающие на реальную опасность.

Примеры

Пример 1. Заголовочный файл стороннего производителя. Библиотечный заголовочный файл, который вы не можете изменить, может содержать конструкцию, которая приводит к (вероятно, мелкому) предупреждению. В таком случае "заверните" этот файл в свой собственный, который будет включать исходный при помощи директивы #include и избирательно отключать для него конкретные предупреждения. В своем проекте вы будете использовать собственный заголовочный файл, а не исходный. Например (учтите — управление выводом предупреждений варьируется от компилятора к компилятору):

// Файл: myproj/my_lambda.h - "обертка" для lambda.hpp из



Поделиться книгой:

На главную
Назад