За что я люблю язык С
Пришлось тряхнуть стариной и написать несколько сотен строк кода на С. Лет десять уже этим не занимался, расслабился и огреб по полной программе:
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
Метки: C Рубрики: Разработка, Языки
ЖЖ
11 комментариев
Походу дела, тут просто опечатка. вместо strlen (str + 1) нужно написать strlen (str) + 1. Причем тут C, и причем тут вообще все? Ну, отпечатался, с кем не бывает.
С переходом на Java я не стал делать меньше опечаток. Но большинство из них ловятся при компиляции. Про остальные получаю четкую информацию при возникновении исключения. И не припомню случаев, чтобы подобная ошибка в Java приводила к такому непростому поведению программы.
Язык должен помогать исправлять опечатки. А в С все потроха наружу. При всём уважении — пора ему и на покой.
Java это как строгая мама, то не делай, это не далай, я если убей, нужно сделать, напялит на тебя каску и бронежилет. C же разрешает все. В этом его преимущество, в этом и не достаток. Я на C тоже на программирую, но у нас в команде C используется широко, и даже ассемблер. При кодировании/декодировании видео борьба идет за каждый процент.
Так давно пора сделать язык для критичных к производительности компонентов, который при эффективности С будет обладать бОльшей безопасностью!
ИМХО тут дело в компромиссе либо безопасность, либо скорость.
Категорически не согласен с противопоставлением безопасности и производительности. Просто во времена K&R, похоже, никто не задумывался о безопасности. Сейчас бы всё сделали по-другому.
Простите, чем strdup () не устроил?
Остальные библиотечные функции не было
желания тоже переписать с ошибкой?
)
Говорю же — на С почти не пишу. Не знать всю библиотеку — наказуемо? К тому же смысл не в этом — такую ошибку можно и в другом месте сделать.
За годы использования С, выработались
правила и стандарты, следуя которым, можно
избежать основную массу ошибок. В данном
конкретном случае спасло бы правило не
переделывать библиотечные функции (и да, знать
их надо, разумеется).
Если же мы рассматриваем данную ошибку в
произвольном контексте, то вы же по-просту
не верно расставили скобки. От этого не спасёт ни
один язык или компилятор: скобки можно перепутать
просто при записи математического выражения.
Я не отрицаю, что, ошибки доступа к памяти, java
исключает, но скобки перепутать всё равно найдётся где.
Если бы я перепутал скобки в Java, то получилось бы сложение String и int. Ошибку было бы найти гораздо проще — достаточно одного взгляда на строку. А то и на этапе компиляции ошибка бы вылезла из-за несовместимости типов, например, Object + int.
Я в первую очередь жалуюсь на очень неочевидную связь между причиной и следствием при порче памяти в С. Похожую ошибку в Java исправить в разы легче.
Ну, в Java такой функции, которую вы написали
на С, не могло бы быть по определению, по тому
считаю сравнение не корректным. Вы бы не стали
там ничего прибавлять к указателю, так как и указателей нет.
А просто напутав скобки в математическом выражении,
можно тоже получить трудноотлавливаемый глюк.
Но да, адресной арифметики там нет, следовательно,
все ошибки адресной арифметики там исключены...
Вы утверждаете, что этого бы хватило для полного
счастья? А я утверждаю, что, для написания качественного
кода, даже на Java, всё равно нужен опыт и следование
различным правилам хорошего тона в программировании.
Написать комментарий