LINUX.ORG.RU

Написал небольшую книгу для C/C++ программистов

 , , , ,


13

8

Здравствуйте. Меня зовут Андрей Карпов. Сфера моих интересов - язык C/C++ и продвижение методологии статического анализа кода. На протяжении пяти лет я являюсь Microsoft MVP в номинации Visual C++. Основная цель моих статей и работы, сделать код программ немножко безопасней и качественней. Буду рад, если эта мини-книга научит вас писать более надежный код и предостережет от некоторых типовых ошибок. Немало полезного здесь можно будет почерпнуть и тем, кто занимается написанием стандартов кодирования для своих компаний.

Немного истории. Не так давно я создал ресурс, на котором делился различными полезными советами по программированию на языке С++. Ресурс не собрал ожидаемое количество подписчиков, поэтому я не вижу смысла приводить здесь на него ссылку. Сайт просуществует какое-то время, после чего уйдет в небытие. А вот советы достойны сохранения. Поэтому я доработал, пополнил эти советы и объединил их в единый текст. Желаю приятного чтения.

UPD: PDF-версия: https://yadi.sk/i/RCHauHFBr2cSs

P.S. Пользуясь случаем приглашаю всех желающих последовать за мной в Twitter: @Code_Analysis.

>>> Главный вопрос программирования, рефакторинга и всего такого



Проверено: beastie ()
Последнее исправление: Aceler (всего исправлений: 3)
Ответ на: комментарий от mersinvald

Ну, если изначально использовать инструменты, которые совместимы не только сами с собой, то ничего ехать и не будет. А так... ой, я открыл doc/docx и у меня все поехало... ССЗБ.

Deleted
()
Ответ на: комментарий от Andrey_Karpov_2009

скопировать нужный кусочек из достойного места

Кстати, отличный способ скопировать к себе уязвимость, которую потом поправят в этой библиотеке, а ты нет.

Aceler ★★★★★
()

Мне кажется ТС изрядно доставляют неформальная ЛОРовская фауна и срачи в комментариях, иначе я не понимаю почему он до сих пор здесь, учитывая то количество говна, которое на него льется (иногда по делу, но по большей части — нет)

mersinvald ★★★★★
()
Ответ на: комментарий от Deleted

Если так, мне кажется, что-то сильно не в порядке с тем, как этот цикл реализован в компиляторе. Хотите скорости - пишите на ассемблере.

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

1. Не все люди больны. Именно поэтому помимо ассемблера приходится писать быстрее на языках более высокого уровня.

2. Да, разворачивание цикла иногда может дать прирост по производительности. И не тебе, невежда, решать, когда, кому и на чём писать код драйверов, которые ОБЯЗАНЫ работать быстро, что бы ты там по читабельности не хотел в своих представлениях о хороших компиляторах.

ThisNameWasFree
()
Последнее исправление: ThisNameWasFree (всего исправлений: 2)

По теме: большую часть читать не интересно, ибо многое выводится просто из собственного опыта, кое что для себя нового тем не менее подчерпнул, за это спасибо.
Пресловутый пункт 41 никуда не годится: ИМХО, следует ввести пометку, мол вендоспецифика.
Да, тащить либу ради CRC, когда функция расчета 10 строк + таблица — бред, это наравне с недавними казусами с npm и библиотеками-однострочниками, но если речь о всяких PNG, то в приоритете переносимость кода и прибивать libpng — значительно меньшее зло, чем прибивать код к винде.
Хуже только писать на VC++, вместо чистого переносимого C++

mersinvald ★★★★★
()
Последнее исправление: mersinvald (всего исправлений: 3)

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

Без обид, но всерьез обсуждать сравнение с 1 и -1 вместо < или > 0 может только полный дэбил.

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

AVL2 ★★★★★
()
Ответ на: комментарий от AVL2

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

Безумие писать неверный код. Какая разница, насколько быстро он неправильно работает.

Andrey_Karpov_2009
() автор топика
Ответ на: комментарий от Andrey_Karpov_2009

Безумие - это наклепать кучу страниц текста рекламы проприетарного статического анализатора, нафигачить кода со ссылками на MSDN и ворваться на форум линуксоидов с криком «а вот у меня ещё твиттер есть». Блин, да я поражён как вас тут ещё не послали лесом. Вы же очевидный идеологический противник всего прекрасного местной тусовки.

ThisNameWasFree
()
Ответ на: комментарий от segfault

Поправочка: язык программирования не решает _никаких_ проблем.

Поправочка: язык программирования их *создаёт*. Или нет. Зависит от языка. Вернее, его автора.

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

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

debugger ★★★★★
()
Ответ на: комментарий от Andrey_Karpov_2009

Безумие писать неверный код. Какая разница, насколько быстро он неправильно работает.

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

Если бы эта лшибка была критична, ее бы и нашли гораздо раньше.

AVL2 ★★★★★
()
Ответ на: комментарий от mersinvald

…иначе я не понимаю почему он до сих пор здесь, учитывая то количество говна…

Реклама. Индекс цитирования.

debugger ★★★★★
()
Ответ на: комментарий от Displacer

Если что, то в РФ и на постсоветском пространстве широко распространён формат fb2

Художественная литература о С++? Это же не perl, все-таки!

annulen ★★★★★
()
Ответ на: комментарий от tailgunner

Долистал до середины, детвора смеется :D

Какая это книга, это буклет мамкиного кодера. Читайте классику, пацаны.

arturpub ★★
()
Ответ на: комментарий от Meyer

Компилятор не всегда справляется, иногда (часто) ему приходится помогать.

yoghurt ★★★★★
()

Понятно, фтопку.

Первый же пример...

Я бы порекомендовал переписать эту функцию так:
static int rr_cmp(uchar *a,uchar *b)
{ 
  for (size_t i = 0; i < 7; ++i)
  { 
    if (a[i] != b[i])
      return a[i] - b[i];
  } 
  return a[7] - b[7];
}
Magic numbers во все поля, нет проверки выхода за пределы массива, если это C++, то какие к черту uchar*, вместо vector<uchar>...

Тебя ничему история с strcpy, strcmp и прочими не научила (типичная причина stack-overflow)?

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от Andrey_Karpov_2009

Безумие писать неверный код. Какая разница, насколько быстро он неправильно работает.

Так твой вариант так же не верен без «анализа частоты выполняемого кода и того, кода, который...»

TDrive ★★★★★
()
Ответ на: комментарий от invy

Не в тему.
Автор просто переделал пример из кода мускуля.

Да и какие нахрен векторы и прочие шаблонные контейнеры работающие поверх кучи, когда речь о высокопроизводительном софте?

mersinvald ★★★★★
()
Ответ на: комментарий от mersinvald

Да и какие нахрен векторы и прочие шаблонные контейнеры работающие поверх кучи, когда речь о высокопроизводительном софте?

Вектор не обязан работать поверх кучи.

tailgunner ★★★★★
()

Спасибо. Больше литературы. Так держать. Единственное - реклама. Да вынесите Вы свой инструмент в отдельную главу, заодно и доку по нему сделаете.

kedr
()
Ответ на: комментарий от Deleted

При наличии SSD, i7 и 32 Гб оперативки молниеносно работать будет любой код. xD

молниеносно работать будет любой код

любой код

Увы.

znenyegvkby
()
Ответ на: комментарий от mersinvald

Какая разница, откуда он код привел, он делает ту же ошибку по сути - в трёх разных местах напишет 7. Если завтра будет не 7, а 6, а функцию изменить забудет - всё накроется медным тазом. Если он во время написания этой функции совершит опечатку и вместо 7 напишет 8 в одном из трёх мест - всё накроется медным тазом. Если вызывающая функция создаст меньший массив, или еще веселее, кстати, передаст тупо nullptr - всё накроется медным тазом. (Да, я про проверку на nullptr в этом куске кода забыл).

Короче говоря, рекомендация автора - это самый настоящий говнокод, выдаваемый за улучшение.

invy ★★★★★
()
Ответ на: комментарий от invy

Короче говоря, рекомендация автора - это самый настоящий говнокод, выдаваемый за улучшение.

Там поинт только в том, что кода меньше. Читабельность, все дела xD

znenyegvkby
()
Ответ на: комментарий от Andrey_Karpov_2009

Без рекламы.

Да, но зачем она тогда мне. :))

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

Не понимаю зачем её вообще запихали в мининовость?

TDrive ★★★★★
()
Последнее исправление: TDrive (всего исправлений: 1)
Ответ на: комментарий от invy

Еще раз, это in-place улучшение конкретного отрывка кода.
Перекраивание архитектуры мускуля глобально по вашим диванным бредням — совершенно отдельная тема для разговора.

mersinvald ★★★★★
()
Ответ на: комментарий от tailgunner

Окей, не обязан, просто в голову первым делом пришел std::vector.
В любом случае, рантаймовым проверкам выхода за границы не место в хайлоад продакшене.

mersinvald ★★★★★
()
Ответ на: комментарий от mersinvald

рантаймовым проверкам выхода за границы не место в хайлоад продакшене.

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

P.S. хайлоад - это много-много серверов с похапе.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

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

mersinvald ★★★★★
()
Последнее исправление: mersinvald (всего исправлений: 1)
Ответ на: комментарий от mersinvald

диванным бредням

Это опыт. Я очень много видел проблем именно из-за такого кода.
Хочешь in-place, минимальными жертвами? Пожалуйста. Одной строки достаточно.

static int rr_cmp(uchar *a,uchar *b)
{
  // arrays are expected to have more, then 8 elements
  // if not, we're in deep shit.
  const size_t LAST_IDX = 7;
  for (size_t i = 0; i < LAST_IDX; ++i)
  { 
    if (a[i] != b[i])
      return a[i] - b[i];
  } 
  return a[LAST_IDX] - b[LAST_IDX];
}
Кстати, куда автор подевал приведение типов?

invy ★★★★★
()
Ответ на: комментарий от mersinvald

У оператора [] нет проверки выхода за границу.

invy ★★★★★
()
Ответ на: комментарий от mersinvald

Не вижу препятствий

Ну окей.

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

Хайлоад, массивы, БД... какие-то эротические сны школьника.

tailgunner ★★★★★
()
Ответ на: комментарий от mersinvald

В их отсутствии, очевидно. Я бы сделал еще лучше - ввел новую функцию:

static int rr_cmp_n(uchar *a,uchar *b, const size_t LAST_IDX)
А оригинальную обозвал бы deprecated, чтобы при каждой сборке кричало что «депрекейтед, блджад!».

invy ★★★★★
()
Ответ на: комментарий от ThisNameWasFree

которые в матчасти не секут

Допустим. Это оправдывает компилятор, не способный делать оптимизацию, из-за чего приходится писать индусский код?

Deleted
()
Ответ на: комментарий от mersinvald

Аргументация у тебя

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

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

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

Не надо выпадать из реальности. Академический подход с максимальной безопасностью и собственной субъективной правильностью не всегда уместен.

mersinvald ★★★★★
()
Последнее исправление: mersinvald (всего исправлений: 1)
Ответ на: комментарий от mersinvald

Опять же, высосано из пальца.

mersinvald > впихни проверки в хайлоад в каждом цикле над массивами и контейнеры заместо оных массивов и пусть клиенты наслаждаются скоротечным течением сакуры, которое пройдет быстрее, чем их запросы к твоей БД.

Да, это высосано из пальца.

Не надо выпадать из реальности.

Чтобы из нее выпасть, сначала надо в ней появиться.

tailgunner ★★★★★
()
Ответ на: комментарий от znenyegvkby

Разворачивать циклы - последняя стадия оптимизации, когда менеджер бьет копытом а соответствующая опция компилятора не сработала

TooPar
()
Ответ на: комментарий от tailgunner

Да, это высосано из пальца.

Кто-то не умеет в гиперболы?

Чтобы из нее выпасть, сначала надо в ней появиться.

Первая дельная мысль с твоей стороны

mersinvald ★★★★★
()
Ответ на: комментарий от TooPar

Oh, shit, да что вы говорите? Т.е. вы, как и Карпов, считаете что джуны в скуле настолько тупы, что даже не знают что на Земле существуют лупы, а развертку сделали от невежества? Ай-яй-яй, ну и дегенераты...

znenyegvkby
()
Ответ на: комментарий от mersinvald

Кто-то не умеет в гиперболы?

Кто-то умеет только в гиперболы.

tailgunner ★★★★★
()
Ответ на: комментарий от znenyegvkby

вы, как и Карпов, считаете что джуны в скуле настолько тупы, что даже не знают что на Земле существуют лупы, а развертку сделали от невежества?

Я, как и Кнут, считаю, что преждевременная оптимизация - корень всех зол.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

А вы этот конкретный код анализировали? М.б. именно эта разветка – результат долгих и кропотливых тестов и стараний целой команды.

znenyegvkby
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.