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.

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

Ответ на: комментарий от Meyer

Это работает только в частных случаях.

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

RazrFalcon ★★★ ()

Опять реклама PVS Studio. Опять на ЛОРе. Ну не идет в среде линуксятников внедрение плагина для MSVS, хоть ты тресни!

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

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

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

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

Ну критикоать много ума не надо. Другое дело - предложить...

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

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

Спасибо, а то по дороге на и с работы сеть ведёт себя как попало, хоть прочитать смогу. Да и просто хранить чуть удобнее.

grem ★★★★★ ()

Я, как и остальные, все же не могу пройти против дикого, 41-го пункта.

  1. Виндопроблемы.
  2. Виндопроблемы. Библиотека, с большей долей вероятности, будет покрыта тестами, в отличии от.
  3. Виндопроблемы. «В больших проектах постоянно „отваливается“ то одно то другое» - это многое говорит о организации проекта.
  4. Виндопроблемы + троллинг FOSS. И это на лоре.
  5. «не понятно, что делать если это произошло» - читать лицензию. Проприетарщики должны страдать.
  6. Конечно же проще самому портировать, чем ждать когда портируют авторы либы...
  7. Либы, заточенные под один компилятор, - ущербны по умолчанию.
  8. Виндопроблемы + ССЗБ. Нечего писать на VC++. Нужно сразу писать на чистом, переносимом C++.
  9. ССЗБ. Зачем использовать C либы без врапперов.
  10. См. пункт 3
  11. «Есть масса других негативных моментов, о которых я не помню и не знаю.» - 11/10

В очередной раз убеждаюсь, что MS ломает людям мозг.

RazrFalcon ★★★ ()

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

Здорово, вы явно умеете продвигать ресурсы

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

В дополнение к 41-му пункту:

Но даже работая с PNG, надо остановиться и подумать. А нужна ли библиотека? Какие операции нужно выполнять с изображениями? Быть может, если вся задача сводится к тому, чтобы сохранить какое-то изображение в *.png - файл, можно обойтись системными функциями. Например, если у вас Windows приложение, то вам поможет WIC. А если вы уже используете библиотеку MFC, то вообще не надо усложнять код, ведь есть класс CImagе. Минус одна библиотека - отлично!

Прибили приложение гвоздями к винде - отлично! К черту кроссплатформенность!

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

Такой код очень сложно профилировать, так как он сразу инлайнится.

Есть большая вероятность, что я наломал дров.

#include <stdio.h>
#include <sys/types.h>

// 32 000 инструкций 
static int rr_cmp(u_char *a, u_char *b)
{
    if (a[0] != b[0])
        return (int) a[0] - (int) b[0];
    if (a[1] != b[1])
        return (int) a[1] - (int) b[1];
    if (a[2] != b[2])
        return (int) a[2] - (int) b[2];
    if (a[3] != b[3])
        return (int) a[3] - (int) b[3];
    if (a[4] != b[4])
        return (int) a[4] - (int) b[4];
    if (a[5] != b[5])
        return (int) a[5] - (int) b[5];
    if (a[6] != b[6])
        return (int) a[6] - (int) b[6];
    return (int) a[7] - (int) b[7];
}

// 55 000 инструкций
static int rr_cmp2(u_char *a,u_char *b)
{
    for (size_t i = 0; i < 7; ++i) {
        if (a[i] != b[i])
            return a[i] - b[i];
    }
    return a[7] - b[7];
}

int main(int argc, char *argv[])
{
    u_char s1[] = "teststr";
    // костыль, чтобы компилятор не оптимизировал цикл до 1-й итерации
    int v1[1000];
    int v2[1000];

    for (int i = 0; i < 1000; ++i) 
        v1[i] = rr_cmp(s1, s1);

    // костыль, что бы компилятор не удалял код
    printf("%i\n", v1[0]);

    for (int i = 0; i < 1000; ++i) 
        v2[i] = rr_cmp2(s1, s1);
    printf("%i\n", v2[0]);

    return 0;
}

clang -O2 -fno-inline main.cpp
RazrFalcon ★★★ ()

Дочитал до 9-ого пункта. Часть проблем Win-специфична, почти все иные связаны исключительно с врождёнными травмами Си, которые в Си++ перенесены для совместимости. Если бы в языке был нормальный логический тип и символьный тип, если бы не использовались нуль терминированные строки, если бы не нужно было явно выделять память на каждый чих, если бы не приходилось всякий рах пользоваться макросами, все эти ошибки бы не произошли.

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

Но ведь это правда. Иначе вы отрицаете очевидное. Проблема в том, что Си++ почти всегда используется там, где его можно заменить на другой, более удобный и безопасный вариант, будь то Го, Ява, Д. Даже Паскаль решит многие проблемы, упомянутые в статье, за счёт строгой типизации и полуавтоматического управления памятью.

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

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

Те же кто возражает, к сожалению, просто не опытны и не видели адовую жизнь в больших проектах, отягощенных злом библиотеками. И моя миссия хоть кого-то заранее предупредить куда ведёт дорого «добавим библиотеку». Даже одна спасённая душа спасённый проект, это уже хорошо.

прослезился

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

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

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

А вывод до банального прост. Все, кто использует в своих проектах сторонние библиотеки – будут гореть в аду!

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

Все, кто использует в своих проектах сторонние библиотеки – будут гореть в аду!

что, на питоне тоже нельзя??

ушел каяться

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

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

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

cloudflare попробуйте или любой другой CDN, оно и проблемы с SSL решит (чтобы попробовать и бесплатно плана хватит, кстати) Только желательно, перед тем как пробовать, ip-aдрес все-таки поменять.

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

С тем, что С и С++ очень часто используются не по назначению - согласен. Однако, прокомментированное мною утверждение о том, что их следует _повсеместно_ заменять на более высокоуровневые языки неверно.

Даже Паскаль решит многие проблемы, упомянутые в статье

Поправочка: язык программирования не решает _никаких_ проблем. Он может разве что _заствить_ программиста их решить, в виду невозможности или сложности некоторых «финтов», доступных в С.

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

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

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

И настолько же правильно.

tailgunner ★★★★★ ()

сносная книжка, но до Майерса не дотягивает.

и прибита сильно к уиндоус.

совет 6 я б назвал «Остерегайтесь типа long»

в Linux sizeof(long) == sizeof(void*) (до кучи можно и DOS припомнить)

ну и всякие _T(), DllMain и т.п.

можно б было разделить на 2 книжки С++ и С++ для уиндоус.

а так более-менее, хотя рекламы PVS-Studio многовато.

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

можно б было разделить на 2 книжки С++ и С++ для уиндоус.

Думаю, что достаточно просто сгруппировать вопросы, т.е. сделать две главы/части одной книжки.

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

за счёт строгой типизации и полуавтоматического управления памятью.

Вы видимо не в курс что такое C++11 и что такое хороший код на C++. Там и строгая статическая типизация и автоматическая работа с памятью.

Все приведенные ТС примеры - это, увы, быдлокод и последствия написания в стиле C-с-классами. Да, запретить это нельзя, но это не значит что весь код такой.

Если человек готов жертвовать производительностью - пусть пишет на чём угодно. Это его право. Но если у человека не две извилины в голове, он в состоянии использовать нужный ему инструмент.

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

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

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

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

Зачем нам телескоп, если есть подзорная труба. Её намного проще носить с собой. А удобство - это самое главное.

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

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

В Linux всё проще. Я видел адовые внутренности KDE — достаточно большой проект? На плюсах, между прочим.

Проблемы были вовсе не с библиотеками, коих там было достаточно много.

Aceler ★★★★★ ()

Народу, для чистого Си книга нужна по программированию безопасному и без рекламы. Без рекламы. На русском.

VKraft ()
Ответ на: комментарий от MyTrooName

ms word уже сохраняет в latex? значит не нужно

Открыл через Writer, сохранил через Writer2Latex. Et voila!

Aceler ★★★★★ ()

Сделаю свою критику чуть конструктивнее

язык C/C++

Больше так не пиши.
Во-первых, у тебя буквы «С» в обоих случаях кириллические.
А во-вторых, это два совершенно разных языка.

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

Открыл через Writer, сохранил через Writer2Latex. Et voila!

а writer уже нормально открывает MS документы?

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

Зачем нам телескоп, если есть подзорная труба. Её намного проще носить с собой. А удобство - это самое главное.

ты топиком промахнулся

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

а writer уже нормально открывает MS документы?

А можно открыть через WPS, сохранить через него, и открыть в LO. Потом час править съехавшую (но не так сильно, как если бы напрямую) разметку и экспортировать в Latex! Et voila! Куда лучше, чем использовать проверенные временем удобные инструменты!

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

Куда лучше, чем использовать проверенные временем удобные инструменты!

это какие?

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

Мое имхо: код должен быть читаемым, даже если это за счет производительности. Хотя как так может быть? Развернутый цикл быстрее обычного, поэтому давайте гнать индусский код? Если так, мне кажется, что-то сильно не в порядке с тем, как этот цикл реализован в компиляторе. Хотите скорости - пишите на ассемблере.

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

Ну так, а ты думал почему код MS так молниеносно работает? Все из-за вручную развернутых индусских циклов.

mersinvald ★★★ ()

Вы угадали, ответ - 48. Именно столько раз в статье «про программированию на C++» упоминается PVS-Studio. Кто не верит - посчитайте сами.

Diff ★★★ ()

Да... про библиотеки АДИЩЕ

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

Ты ещё спроси, нормально ли он сохраняет в Latex ;-)

Документ того уровня, что по ссылке — откроет нормально.

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

Если человек тянет библиотеку криптографии/архивирования только из-за того, что ему потребовался CRC32 - то да, шлёпать и заставлять писать свой вариант (скопировать нужный кусочек из достойного места).

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

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