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

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

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, всё равно нужен опыт и следование

    различным правилам хорошего тона в программировании.

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