LINUX.ORG.RU

Я вообще представить ситуацию, где нужно проверять значение printf, не могу. Разве что обрыв ssh/telnet какой-нибудь определить, но ни разу не видел, чтобы кто-то проверял. Здесь принцип не работает — просто падаем, обычно.

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

printf

Речь идёт о sprintf, которая пишет в буфер. Необходимо динамически сгенерировать текст. Для этого sprintf вызывается несколько раз и каждый раз возвращаемое значение прибавляется к указателю на буфер. Таким образом, функция каждый раз пишет в конец буфера.

u5er ★★
() автор топика

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

То, что семейство функций printf() возвращает ошибку - лучше, чем void, но бесполезно в 99.99% случаев.

Bfgeshka ★★★★★
()

Не знаю насколько это актуально для gnu libc, но есть такое: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html Там про errno расписано.

Или вам именно личный опыт нужен?

mky ★★★★★
()
Последнее исправление: mky (всего исправлений: 2)

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

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

Я как-то писал весьма специфическую программу на C и столкнулся, наверное, со всеми возможными ошибками связанными с *printf функциями и прочитал с десяток их реализаций. Только я тебе ничего из этого не расскажу, во-первых, потому ты не задал конкретного вопроса, во-вторых, потому что программирование детерминировано, и ответы получают из документации и исходников, а не опыта горстки посетителей забытого богом помоечного форума, в-третьих, тебе скорее всего не нужно дифференцировать ошибки, ибо причиной ошибки возвращаемой snprintf’ом может быть только ошибка в твоём коде. И в-нулевых, конечно же, не нужно никогда использовать sprintf когда есть snprintf.

anonymous
()

Нет, не сталкивался. Более того, sprintf() я стараюсь не использовать в пользу snprintf(), а snprintf() тоже стараюсь не использовать в пользу своей реализации форматированного вывода, в которой поведение везде однозначное без подобной мути.

Что касается теории, то sprintf() может вернуть -1 если ты переполнишь счётчик символов int (да, он мало того что не size_t, так ещё и знаковый, так что переполнить его вполне возможно на практически любой архитектуре, самое простое конечно на 16-битной), а ещё, поскольку glibc совершенно бесстыдно использует malloc-и по делу и не по делу - они есть и внутри sprintf и могут сделать ENOMEM.

Кроме того, некоторые древние реализации snprintf возвращали -1 если не влезают в буфер.

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

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

Да, кто же такое помнит :) Обычно, если sprintf() возвращает -1, то выпходить с ошибкой и всё.

Когда-то давно, вроде, видел программу, у которой строка форматирования задавалась в исходных данных (пользователем). И, ЕМНИП, там в случае -1, проверялся errno, чтобы сообщить, что ошибка в этой строке. Какая там была libc, был ли там parse_printf_format(), вобще не помню.

mky ★★★★★
()

Я сталкивался. Мой коллега написал говнокод, передающий некорректное количество параметров в snprintf. Это был ядерный говнокод, поэтому sprintf засирал стек и всё падало.

К слову, коллега был сишником с 20-летним на тот момент стажем, который, как и многие форумчане тут, презирал все эти новомодные Rust и прочую хипстоту.

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

К окулисту загляни на досуге ;)

Если ты настаиваешь на этом вопросе, ок: да сталкивался, и знаю кейсы для как минимум 3 errno. Почему правильно будет их не расписывать я объяснил.

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

К слову, коллега был сишником с 20-летним на тот момент стажем, который, как и многие форумчане тут, презирал все эти новомодные Rust и прочую хипстоту.

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

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

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

aiqu6Ait ★★★★
()

sprintf это моветон в общем случае

https://learn.microsoft.com/ru-ru/cpp/c-runtime-library/reference/sprintf-spr...

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

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 3)