За что я люблю язык С

Пришлось тряхнуть стариной и написать несколько сотен строк кода на С. Лет десять уже этим не занимался, расслабился и огреб по полной программе:

static char* stralloc( const char* str ) {
    char* res = malloc( strlen( str + 1 ) );
    strcpy( res, str );
    return res;
}

Код выглядит как настоящий, замыленным взглядом ошибку увидеть сложно. А уж какие эффекты появляются! Эта функция вызывалась из двух мест:

static char* start() {
    return stralloc( "{'start':true}" );
}
 
static char* stop() {
    return stralloc( "{'stop':true}" );
}

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

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

27.05.2010  Метки:   Рубрики: Разработка, Языки

11 комментариев

  1. Anton - 27.05.2010

    Походу дела, тут просто опечатка. вместо strlen(str + 1) нужно написать strlen(str) + 1. Причем тут C, и причем тут вообще все? Ну, отпечатался, с кем не бывает.

  2. allex - 27.05.2010

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

    Язык должен помогать исправлять опечатки. А в С все потроха наружу. При всём уважении — пора ему и на покой.

  3. Anton - 28.05.2010

    Java это как строгая мама, то не делай, это не далай, я если убей, нужно сделать, напялит на тебя каску и бронежилет. C же разрешает все. В этом его преимущество, в этом и не достаток. Я на C тоже на программирую, но у нас в команде C используется широко, и даже ассемблер. При кодировании/декодировании видео борьба идет за каждый процент.

  4. allex - 30.05.2010

    Так давно пора сделать язык для критичных к производительности компонентов, который при эффективности С будет обладать бОльшей безопасностью!

  5. Anton - 31.05.2010

    ИМХО тут дело в компромиссе либо безопасность, либо скорость.

  6. allex - 31.05.2010

    Категорически не согласен с противопоставлением безопасности и производительности. Просто во времена K&R, похоже, никто не задумывался о безопасности. Сейчас бы всё сделали по-другому.

  7. stsp - 13.05.2011

    Простите, чем strdup() не устроил?
    Остальные библиотечные функции не было
    желания тоже переписать с ошибкой? :))

  8. allex - 13.05.2011

    Говорю же — на С почти не пишу. Не знать всю библиотеку — наказуемо? К тому же смысл не в этом — такую ошибку можно и в другом месте сделать.

  9. stsp - 13.05.2011

    За годы использования С, выработались
    правила и стандарты, следуя которым, можно
    избежать основную массу ошибок. В данном
    конкретном случае спасло бы правило не
    переделывать библиотечные функции (и да, знать
    их надо, разумеется).
    Если же мы рассматриваем данную ошибку в
    произвольном контексте, то вы же по-просту
    не верно расставили скобки. От этого не спасёт ни
    один язык или компилятор: скобки можно перепутать
    просто при записи математического выражения.
    Я не отрицаю, что, ошибки доступа к памяти, java
    исключает, но скобки перепутать всё равно найдётся где.

  10. allex - 13.05.2011

    Если бы я перепутал скобки в Java, то получилось бы сложение String и int. Ошибку было бы найти гораздо проще — достаточно одного взгляда на строку. А то и на этапе компиляции ошибка бы вылезла из-за несовместимости типов, например, Object + int.

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

  11. stsp - 13.05.2011

    Ну, в Java такой функции, которую вы написали
    на С, не могло бы быть по определению, по тому
    считаю сравнение не корректным. Вы бы не стали
    там ничего прибавлять к указателю, так как и указателей нет.
    А просто напутав скобки в математическом выражении,
    можно тоже получить трудноотлавливаемый глюк.
    Но да, адресной арифметики там нет, следовательно,
    все ошибки адресной арифметики там исключены…
    Вы утверждаете, что этого бы хватило для полного
    счастья? А я утверждаю, что, для написания качественного
    кода, даже на Java, всё равно нужен опыт и следование
    различным правилам хорошего тона в программировании.

Написать комментарий