LINUX.ORG.RU
ФорумTalks

Вопрос по истории C'шечки

 


0

3

Как можно было функции типа atoi, которые не различают отсутствие конвертируемой в число строки от легитимного значения, пропихнуть во все мыслимые стандарты Юникс и C? В те времена С'шникам было покласть на баги?

★★★★★

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

Нет. atoi вообще пример как не надо делать - и обработка аргумета, и код возврата. Но я говорил про обработку аргумента.

Сигнатура (аргументы + возврат) фунции atoi — это самая минималистичная сигнатура разборщика строк в числа. Не даём возможности продолжить парсинг, не даём возможности выдать ошибку при разборе, не даём возможности выбрать основание. Максимальная производительность там, где весь этот «лишний обвес» не нужен. Кому не нравится — так есть же более удобные функции, разве заставляют пользоваться этой?

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

Если бы atoi вела себя как результат комбинации парсеров, то как она должна была бы по-твоему работать? Возвращать 0? Других вариантов нет.

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

Кому не нравится — так есть же более удобные функции, разве заставляют пользоваться этой?

См. выше о персонажах, лезущих из щелей.

atoi вела себя как результат комбинации парсеров, то как она должна была бы по-твоему работать? Возвращать 0? Других вариантов нет.

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

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

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

Ок, с этим утверждением согласен.

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

Не факт. gets() слишком толсто, так сказать

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

что является least surprise

Это сильно зависит от контекста(а именно от удивляемого). Так что спор заведомо не имеет смысла

Deleted
()

Обычная минималистическая функция, выполняющая ровно то, что описано, максимально просто и быстро. Как и подавляющее большинство в stdlib. От некорректных строк не ломается, побочных эффектов не имеет… Валидация ввода — не её задача. Вполне классический подход, и не мудрено, что она оказалась в стандарте.

Правда сейчас уже немного deprecated функцией strtol, которая лучше подходит для построения парсеров и умеет не только десятичные числа.

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

Кстати, вспомнил свою atoi для одного встраиваемого проекта:

long atoi(const char *a) {
    char c, *s = a;
    long i = 0;

    while (c = *s++) i = (i << 3) + (i << 1) + (c - '0');
    return i;
}

Никаких тебе проверок: полное доверие ко входным данным. И при этом оно умудрялось работать в АСУ ТП немаленького предприятия. :)

baka-kun ★★★★★
()
Ответ на: комментарий от ixrws

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

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

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

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

Если программиста пугает простота неправильного использования какого-либо API, то низкоуровневые языки не для него.

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

Если программиста пугает простота неправильного использования какого-либо API, то низкоуровневые языки не для него.

Если программиста не пугает простота неправильного использования какого-либо API, программирование не для него.

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

Если программиста не пугает простота неправильного использования какого-либо API, программирование не для него.

Я в тред зашел не в красноречии поупражняться, а изложить реальное положение вещей в сфере embedded и системного программирования, где я кручусь уже много лет. А в ответ - фраза уровня «сам ты дурак».

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

Я в тред зашел не в красноречии поупражняться, а изложить реальное положение вещей в сфере embedded и системного программирования,

Это реальное положение вещей в совсем другой сфере.

где я кручусь уже много лет.

Я тоже. Но еще я знаю историю языков программирования (ага, Си в том числе).

А в ответ - фраза уровня «сам ты дурак».

Моя фраза - зеркальное отражение твоей. Если ты видишь там «сам дурак» - это твои слова.

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

Эмбед вообще отдельный мир.

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

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

А можно поподробнее на счет небезопасности данной функции? И как другие, «безопасные» функции проверяют битые указатели или строки без нул-терминатора?

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

Одно дело коробка с двумя кнопками, а другое - прога (любой сложности) которой пользуется обезьян вводящий произвольные данные.

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

Одно дело коробка с двумя кнопками, а другое - прога

А то в коробку не может попадать всякий мусор…

Валидировать поступающую извне информацию — первое, чему учат разработчиков. Только вот не все выучили. Некоторые даже забывают проверять возвращаемые функциями в/в ошибки. И вообще редко кто проверяет результат close.

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

Некоторые даже забывают проверять возвращаемые функциями в/в ошибки. И вообще редко кто проверяет результат close.

Сишкопроблемы.

RazrFalcon ★★★★★
()

Всё правильно. Роботы в то время ещё не умели справляться с нештатными ситуациями. Да и сегодня ещё не очень. Видать, авторы совершенно резонно решили, что нет смысла пытаться возложить оное на роботов.

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

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

Сишкопроблемы.

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

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

This function is not defined in ANSI-C and is not part of C++, but is supported by some compilers.

Там же и написано. В линуксе я всегда брал имплементацию из k&r (вроде была там, если правильно помню) или писал свою.

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

by some compilers

В эти some входят gcc, clang, tcc и вижуал студия. К тому же вопрос о стандартности не стоял, ты сказал, что такой функции нет, но она есть.

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

Из ОП:

пропихнуть во все мыслимые стандарты Юникс и C

я это и имел в виду. Пруф, что gcc/clang поддерживают itoa? А вижалстудия вообще стремная штука с кучей чисто вендовых примочек.

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

Даже в C++ есть аттрибут, включающий проверку возвращаемого значения на этапе компиляции.

Проверять ошибки реального времени на этапе компиляции? Сильно.

Не важно, что умеет язык, во сколько объектов завернуто, сколько сахара намазано сверху. Если важна сохранность результата, ошибки ввода-вывода нужно проверять, будь то код возврата, errno или исключения. А подавляющее большинство если и проверяет запись в файл, то могут количество реально переданных байт не посмотреть. Ошибку при закрытии файла вообще анализируют единицы.

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

Даже в C++ есть аттрибут, включающий проверку возвращаемого значения на этапе компиляции.

Проверять ошибки реального времени на этапе компиляции? Сильно.

Ты не понял, что тебе сказали. Не проверять ошибки «реального времени» («времени исполнения», конечно же) на этапе компиляции, а требовать написания кода их проверки.

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

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

Ошибку при закрытии файла вообще анализируют единицы.

Это, конечно, печально, но при ошибке закрытия уже поздно что-то делать.

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

Это, конечно, печально, но при ошибке закрытия уже поздно что-то делать.

Гы. Это как раз самое время начинать что-то делать

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

при ошибке закрытия уже поздно что-то делать.

Гы. Это как раз самое время начинать что-то делать

Да? Тогда расскажи, что именно.

tailgunner ★★★★★
()

С'шникам было покласть на баги?

Конечно. Это сейчас все носятся с валидацией, безопасностью и т.п., а раньше спокойно делали, например, char buf[100] и не парились. Время было такое.

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

Это индивидуально, в зависимости от тяжести последствий ) В конце концов, для любого софта часто важнее не то, что он работает в тепличных условиях, а то, что произойдет в нештатной ситуации.

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

Да? Тогда расскажи, что именно

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

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

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

...несмотря на то, что все три часа он нажимал Ctrl-S каждую минуту.

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

Это как раз самое время начинать что-то делать

Да? Тогда расскажи, что именно.

Это индивидуально

«Я знал, что ты скажешь это» (ц)

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

Ошибка может проявиться только на close.


It is quite possible that errors on a previous write(2) operation are first reported at the final close(). Not checking the return value when closing the file may lead to silent loss of data. This can especially be observed with NFS and with disk quota.

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

«Я знал, что ты скажешь это» (ц)

Примите мое сочувствие по случаю вашего неудавшегося троллизма. В другой раз вам непременно повезет

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

Не могу. Всё удалось.

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

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

Я остался таким же, как был

Да-да, совершенно верно. Держись за ручку, сейчас дорогу переходить будем.

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

Держись за ручку, сейчас дорогу переходить будем.

Дяденька, я тебя не знаю и никуда с тобой не пойду. А будешь приставать - ментов позову.

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

«времени исполнения», конечно же

Если ты настаиваешь.

требовать написания кода их проверки.

std::ofstream file("name");
file << string;
file.close();

Хотя обычно даже close() опускают, полагаясь на деструктор.

Проверка записи в файл бесполезна чуть менее, чем совсем.

Ты забыл начать уточнять термины. Что мы подразумеваем под «проверкой»: реакцию на ошибку или вычитку файла, «а вдруг не записалось». :)

Это, конечно, печально, но при ошибке закрытия уже поздно что-то делать.

В некоторых случаях достаточно сказать об этом, и предложить сохранить в другом файле. В некоторых случаях вполне можно слить несохраненные данные в /tmp и сказать об этом. Во всех случаях можно хотя бы сказать об этом, чтобы потеря данных не прошла незамеченной.

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

Ты забыл начать уточнять термины. Что мы подразумеваем под «проверкой»:

Зачем? Ты сказал достаточно:

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

Вполне очевидно, что речь о write(2).

Что мы подразумеваем под «проверкой»: реакцию на ошибку или вычитку файла, «а вдруг не записалось». :)

Ты проверяешь запись файла просто вычиткой из него? Эпично.

при ошибке закрытия уже поздно что-то делать.

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

В некоторых интерактивных программах, которые занимаются исключительно сохранением данных - возможно.

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

Да, это очень важно.

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

Да, это очень важно.

самое главное - что это повод для безотлагательной диагностики

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

Вполне очевидно, что речь о write(2).

Очевидно. Тогда я не понимаю твоего «бесполезно»: любой начинающий программист уже прошел по граблям, когда write записал меньше, чем было в буфере.

В некоторых интерактивных программах

Во всех, где перед сохранением имеются все данные для него, и не теряются после. Редакторы (текстовые, графические…), среды разработки, и так далее… Имя им легион.

Да, это очень важно.

Очень. Silent loss — жутко неприятно.

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

У вас очень странное представление о других языках. Советую расширять кругозор.

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

Вполне очевидно, что речь о write(2).

Очевидно. Тогда я не понимаю твоего «бесполезно»

write(2) бесполезен для _записи_ данные в файл - он просто передает их в кэш. Если тебе действительно нужно записать данные, для этого есть fsync и fdatasync // К.О.

Редакторы (текстовые, графические…), среды разработки, и так далее… Имя им легион.

Имя им - «интерактивный редактор».

Silent loss — жутко неприятно.

Конечно. Но сообщения вида «мужык, я не смогла сохранить данные» тоже жутко неприятны, а это максимум информативности, которого можно достичь на стадии, когда вызывается close. Нужно проверять результат записи, когда еще известен контекст - типа «операция XXX для пользователя YYY завершилась неудачно, состояние осталось неизменным с момента ZZZ». Потому что, как замечено выше, сообщение об ошибке - это начало исправления пролблемы.

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