MSVC постоянно предлагает такие функции, например sprintf_s вместо sprintf (последняя помечена обидным deprecated), тогда как в стандарте C о них ни слова и другие компиляторы их не знают. Приходится руками отключать соответствующие warning'и (или объявлять _CRT_SECURE_NO_DEPRECATE). Собственно вопросы:
1. Это очередная "превосходная фича" от MS или нечто действительно ценное, на что следует обратить внимание?
2. Нужны ли они, применяете ли их вы лично и зачем?
3. Где об этом можно почитать подробнее (какой-нибудь внятный туториал: вот без sprintf_s было плохо, с вот с ним стало хорошо)?
Здравствуйте, Tilir, Вы писали:
T>Вопрос не спешный, я просто любопытствую.
T>MSVC постоянно предлагает такие функции, например sprintf_s вместо sprintf (последняя помечена обидным deprecated), тогда как в стандарте C о них ни слова и другие компиляторы их не знают. Приходится руками отключать соответствующие warning'и (или объявлять _CRT_SECURE_NO_DEPRECATE). Собственно вопросы: T>1. Это очередная "превосходная фича" от MS или нечто действительно ценное, на что следует обратить внимание? T>2. Нужны ли они, применяете ли их вы лично и зачем? T>3. Где об этом можно почитать подробнее (какой-нибудь внятный туториал: вот без sprintf_s было плохо, с вот с ним стало хорошо)?
Вот без него было плохо:
char too_short_buffer[10];
sprintf(buf, "%s", s);
И вот без него было плохо:
char buffer[10];
snprintf(buf, 128, "%s", s);
Вот с ним стало хорошо:
char buffer[10];
sprintf_s(buf, "%s", s);
T>1. Это очередная "превосходная фича" от MS или нечто действительно ценное, на что следует обратить внимание?
Смотри сам. Если для тебя те проблемы, которые решают эти функции являются проблемами, то применяй. Если тебе и так хорошо, и ты никогда не считал это проблемами, то и не парься. Я так думаю.
T>2. Нужны ли они, применяете ли их вы лично и зачем?
Я лично их не применял, т.к. printf сам по себе убогий — неудобный, небезопасный и медленный. И такие навороты ему не помогут. Имхо. Кривого могила исправит
Но если я был вынужден использовать printf, то возможно бы и применял.
T>3. Где об этом можно почитать подробнее (какой-нибудь внятный туториал: вот без sprintf_s было плохо, с вот с ним стало хорошо)?
R>Я лично их не применял, т.к. printf сам по себе убогий — неудобный, небезопасный и медленный. И такие навороты ему не помогут. Имхо. Кривого могила исправит R>Но если я был вынужден использовать printf, то возможно бы и применял.
какие громкие слова...
чем же пользуется маг?
Здравствуйте, Аноним, Вы писали:
R>>Я лично их не применял, т.к. printf сам по себе убогий — неудобный, небезопасный и медленный. И такие навороты ему не помогут. Имхо. Кривого могила исправит R>>Но если я был вынужден использовать printf, то возможно бы и применял. А>какие громкие слова...
ну а чего тут громкого? эти же функции были сделаны... не знаю точно... лет двадцать назад. чего от них ждать?
А>чем же пользуется маг?
Что имхо стоит внимания и чем я пользуюсь (за мага спасибо ):
1. std::ostringstream — это удобно и безопасно. Но не так быстро.
2. boost::format — это ещё удобнее и безопасно. Но ещё медленнее.
3. самописный аналог boost::format — это ещё удобнее, расширяемее, безопаснее и мега быстро, вобщем супер
R>1. std::ostringstream — это удобно и безопасно. Но не так быстро. R>2. boost::format — это ещё удобнее и безопасно. Но ещё медленнее. R>3. самописный аналог boost::format — это ещё удобнее, расширяемее, безопаснее и мега быстро, вобщем супер
скромно так...
фстудию
Re[4]: Security Enhancements in the CRT
От:
Аноним
Дата:
01.03.07 14:53
Оценка:
R>1. std::ostringstream — это удобно и безопасно. Но не так быстро.
насчет удобно — очень спорный момент. как может быть удобно городить(вставлять в текст — _совсем_ не наглядно!) кучу манипуляторов и иже с ними для форматированного вывода? %)
Здравствуйте, Аноним, Вы писали:
R>>1. std::ostringstream — это удобно и безопасно. Но не так быстро. R>>2. boost::format — это ещё удобнее и безопасно. Но ещё медленнее. R>>3. самописный аналог boost::format — это ещё удобнее, расширяемее, безопаснее и мега быстро, вобщем супер А>скромно так... А>фстудию
фсё руки не доходят его фстудию вынести...
но он генерит код аналогичный самописному. даже лучше — мне не удалось руками написать такое же быстрое форматирование. единственный трейдофф — размер машинного кода.
Здравствуйте, Аноним, Вы писали:
R>>1. std::ostringstream — это удобно и безопасно. Но не так быстро. А>насчет удобно — очень спорный момент. как может быть удобно городить(вставлять в текст — _совсем_ не наглядно!) кучу манипуляторов и иже с ними для форматированного вывода? %)
при этом такие "манипуляторы" необходимо применять только когда необходимо "объединить" несколько переменных (как для hex) или когда нужно передать ещё некие настройки (как для даты)
для остальных случаев предусмотрено разумное поведение по-умолчанию:
Здравствуйте, remark, Вы писали:
R>3. самописный аналог boost::format — это ещё удобнее, расширяемее, безопаснее и мега быстро, вобщем супер
Очень хочу поглядеть . Выложи пожалуйста, ну или хоть мне на мыло отправь! У меня есть своя реализация, я ее тут уже гдето выкладывал, видал бустовский формат (больше не хочу его видеть ), хочу вот глянуть как другие умные люди это пишут.
У меня там хитрая архитектура, позволяет в компил-тайм собирать нужный в конкретной ситуации форматтер из блоков-расширений. Например для генератора HTML лога можно отключить расширение выравнивания, тогда скорость форматирования увеличится.
Юзаю так:
// простой пример
formatc("my % formatter") % "super"; // -> "my super formatter"
// расширение выравнивания
formatc("version %<10") %0.2; // -> "version 0.2"
// манипулятор
formatc("hex % number") %sf_hex %0x123; // -> "hex 123 number"
Здравствуйте, Tilir, Вы писали:
T>MSVC постоянно предлагает такие функции, например sprintf_s вместо sprintf (последняя помечена обидным deprecated), тогда как в стандарте C о них ни слова и другие компиляторы их не знают. Приходится руками отключать соответствующие warning'и (или объявлять _CRT_SECURE_NO_DEPRECATE). Собственно вопросы: T>1. Это очередная "превосходная фича" от MS или нечто действительно ценное, на что следует обратить внимание? T>2. Нужны ли они, применяете ли их вы лично и зачем? T>3. Где об этом можно почитать подробнее (какой-нибудь внятный туториал: вот без sprintf_s было плохо, с вот с ним стало хорошо)?
Это неверно, sprintf_s так же требует явного указания размера входного буффера (sprintf_s не занимается магией). Следовательно с этой точки зрения, sprintf_s работает в точности как snprintf.
Разница только в том, что sprintf_s дополнительно проверяет ошибки в форматирующей строке и гарантирует NULL-terminated строку.
Здравствуйте, remark, Вы писали:
T>>3. Где об этом можно почитать подробнее (какой-нибудь внятный туториал: вот без sprintf_s было плохо, с вот с ним стало хорошо)?
Я немножко подкорректировал ваши примеры для наглядности:
R>Вот без него было плохо:
Всё вывалилось в exception, на экране вообще ничего не вывелось.
Давайте разберёмся, а хорошо ли стало?
1. Стало не по стандарту. Я не включаю ничего кроме <stdio.h>, а пользуюсь функциями, про которые любой компилятор, кроме cl спросит "где это"? И будет совершенно прав.
Но, что ещё хуже:
2. А что мне потом с этим exception делать? В стандарте C никаких исключений вообще не прописано — поймать его и обработать можно только в рамках C++, а на C++ ostringstream существенно удобнее.
Вот если бы MS-овская реализация возвращала -1, вместо того, чтобы кидать исключение... Но, если подумать, у нас ведь есть вариант как вернуть -1 вместо исключения, вот он:
// Стало - хорошо!int too_long_integer = 123456789;
char too_short_buffer[5];
int numchar = snprintf(too_short_buffer, 5, "%d", too_long_integer);
if (-1 != numchar)
printf("buffer = %s, numchar = %d", too_short_buffer, numchar)
else
printf("Опаньки");
J>Это неверно, sprintf_s так же требует явного указания размера входного буффера (sprintf_s не занимается магией). Следовательно с этой точки зрения, sprintf_s работает в точности как snprintf.
Здравствуйте, Tilir, Вы писали:
T>Давайте разберёмся, а хорошо ли стало?
T>1. Стало не по стандарту. Я не включаю ничего кроме <stdio.h>, а пользуюсь функциями, про которые любой компилятор, кроме cl спросит "где это"? И будет совершенно прав.
Тебе решать использовать расширения или нет. Никто не обещает, что расширения переносимы.
... хотя скоро может и станет здесь
T>Но, что ещё хуже:
T>2. А что мне потом с этим exception делать? В стандарте C никаких исключений вообще не прописано — поймать его и обработать можно только в рамках C++, а на C++ ostringstream существенно удобнее.
Очевидно, что при компиляции С- кода не могут лететь исключения...
А вообще смотри:
There are versions of sprintf_s that offer additional control over what happens if the buffer is too small. For more information, see _snprintf_s, _snprintf_s_l, _snwprintf_s, _snwprintf_s_l.
T>Вот если бы MS-овская реализация возвращала -1, вместо того, чтобы кидать исключение... Но, если подумать, у нас ведь есть вариант как вернуть -1 вместо исключения, вот он:
T>
Здравствуйте, remark, Вы писали:
R>Чего хорошего? Будет у тебя проект в два раза больше с тем же функционалом....
И медленнее. Кстати никто не ставил эксперимент, выводить в консоль принтфом строчки в цикле. Я заметил, что консоль на VS2005 тормознее раз в 5-10 по сравнению с VS2003 или MinGW. Не связано ли это с майкрософтовскими нововведениями?