Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
vxg
Модератор
 Аватар для vxg
2855 / 1788 / 181
Регистрация: 13.01.2012
Сообщений: 6,720
#1

Вызов sprintf для типа не соответствующего формату - C++

07.10.2016, 16:10. Просмотров 339. Ответов 12
Метки нет (Все метки)

Какова реакция sprintf на передачу в нее значения с типом не соответствующим указанному в формате (UB не предлагать )?
К примеру есть код
C++
1
2
3
4
int64_t x;
char buf[32];
sprintf(buf, "%i", x); //1-й вариант
sprintf(buf, "%i", (int)(x & 0xFFFFFFFF)); //2-й вариант
Оба варианта работают. Однако, программа с первым вариантом иногда падает (статистика для второго варианта еще не сформирована). Такое впечатление, что виновато не место на котором она падает, а что-то хм... большее) Что-то вроде разрушения стека. Кто-нибудь глядел что на самом деле вытворяют va_ макросы и как они извлекают аргументы? Может ли 1-й вариант как то постепенно подтачивать систему (может стек начинает дрейфовать вверх из-за несоответствия размеров типов или не знаю что)?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.10.2016, 16:10     Вызов sprintf для типа не соответствующего формату
Посмотрите здесь:

C++ sprintf и %
C++ Считать данные из файла в динамический массив соответствующего типа
C++ Есть объект типа T, но если вместо него подставить вызов функции, возвращающей T, код не компилится, почему?
C++ Написать программу для вывода символа, соответствующего коду
C++ Вызов конструктора текущего типа
C++ WinAPI sprintf
C++ Вызов типа
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1599 / 991 / 117
Регистрация: 27.09.2009
Сообщений: 1,910
Завершенные тесты: 1
07.10.2016, 18:13     Вызов sprintf для типа не соответствующего формату #2
В данном случае реакция должна быть простейшая, использование 4 байтов из переданного аргумента. Стек чистится в месте вызова, так что данный вызов не должен приводить к ошибкам.

Цитата Сообщение от vxg Посмотреть сообщение
Кто-нибудь глядел что на самом деле вытворяют va_ макросы и как они извлекают аргументы?
Предельно тупо, получают адрес последнего перед эллипсисом аргумента и далее смещают этот адрес на размер очередного извлекаемого типа.

Цитата Сообщение от vxg Посмотреть сообщение
может стек начинает дрейфовать вверх из-за несоответствия размеров типов
Не должен дрейфовать, его чистит вызывающая сторона, которая знает, что и сколько передавала в аргументах.
vxg
Модератор
 Аватар для vxg
2855 / 1788 / 181
Регистрация: 13.01.2012
Сообщений: 6,720
07.10.2016, 18:27  [ТС]     Вызов sprintf для типа не соответствующего формату #3
Nick Alte, получается самое плохое это если принимающая сторона прочитает какую-либо чудь из стека из-за неправильных типов? Это может вызвать AV?
Avazart
 Аватар для Avazart
7037 / 5214 / 259
Регистрация: 10.12.2010
Сообщений: 22,897
Записей в блоге: 17
07.10.2016, 21:49     Вызов sprintf для типа не соответствующего формату #4
Почему не использовать потоки?
C++
1
2
3
4
int64_t x;
std::stringstream ss;
ss << x;
std::string buf= ss.str();
Как реализована функция printf
vxg
Модератор
 Аватар для vxg
2855 / 1788 / 181
Регистрация: 13.01.2012
Сообщений: 6,720
08.10.2016, 07:57  [ТС]     Вызов sprintf для типа не соответствующего формату #5
Avazart, да, можно использовать и поток, но вопрос пока касается не его. Впрочем, вы угадали что все это - аналоги IntToStr, может есть ещё варианты?
Nick Alte
Эксперт С++
1599 / 991 / 117
Регистрация: 27.09.2009
Сообщений: 1,910
Завершенные тесты: 1
08.10.2016, 10:35     Вызов sprintf для типа не соответствующего формату #6
Цитата Сообщение от vxg Посмотреть сообщение
Это может вызвать AV?
Может в том случае, если в строке формата указано нечто указателеобразное (%s, может ещё кто-то, не помню точно).
vxg
Модератор
 Аватар для vxg
2855 / 1788 / 181
Регистрация: 13.01.2012
Сообщений: 6,720
08.10.2016, 10:39  [ТС]     Вызов sprintf для типа не соответствующего формату #7
Nick Alte, нет, там только %i вместо которого передаётся int64_t и даже интерпретируя его как int мы всего лишь попадём в его верхние 4 байта
Nick Alte
Эксперт С++
1599 / 991 / 117
Регистрация: 27.09.2009
Сообщений: 1,910
Завершенные тесты: 1
08.10.2016, 10:50     Вызов sprintf для типа не соответствующего формату #8
Цитата Сообщение от vxg Посмотреть сообщение
там только %i вместо которого передаётся int64_t
В этом случае стеку ничего не сделается. Может быть, проблема в другом месте? Или может она возникает из-за отладочных проверок?
Avazart
 Аватар для Avazart
7037 / 5214 / 259
Регистрация: 10.12.2010
Сообщений: 22,897
Записей в блоге: 17
08.10.2016, 10:57     Вызов sprintf для типа не соответствующего формату #9
Цитата Сообщение от vxg Посмотреть сообщение
Nick Alte, нет, там только %i вместо которого передаётся int64_t и даже интерпретируя его как int мы всего лишь попадём в его верхние 4 байта
По идее проблема может возникать когда следом идет еще несколько аргументов, смещение может идти не верное и следующий арг. будет писаться из оставшихся 4 байт int64_t первого аргумента.

Цитата Сообщение от vxg Посмотреть сообщение
Avazart, да, можно использовать и поток, но вопрос пока касается не его. Впрочем, вы угадали что все это - аналоги IntToStr, может есть ещё варианты?
boost::lexical_cast<>
boost::format()

Не по теме:

Я недавно свой велосипед пытался написать:
https://github.com/Avazart/Bicycle/b...ain_Format.cpp
https://github.com/Avazart/Bicycle/b...ental/Format.h

vxg
Модератор
 Аватар для vxg
2855 / 1788 / 181
Регистрация: 13.01.2012
Сообщений: 6,720
08.10.2016, 11:03  [ТС]     Вызов sprintf для типа не соответствующего формату #10
Avazart, жаль что только буст
Avazart
 Аватар для Avazart
7037 / 5214 / 259
Регистрация: 10.12.2010
Сообщений: 22,897
Записей в блоге: 17
08.10.2016, 11:26     Вызов sprintf для типа не соответствующего формату #11
До С++11 только потоки, boost и фрейворки
После С++11 to_string() и компания.

Там написано что используется тот же std::sprintf так что попробуйте через:
C++
1
std::sprintf(buf, "%lld", value) // std::string to_string( long long value );
Добавлено через 4 минуты
Странно что таких функций в С++ долго не хватало, а когда их ввели, все равно не продумали форматирование/локализацию/преобразование без выкидывания исключения.
vxg
Модератор
 Аватар для vxg
2855 / 1788 / 181
Регистрация: 13.01.2012
Сообщений: 6,720
08.10.2016, 14:06  [ТС]     Вызов sprintf для типа не соответствующего формату #12
Avazart, я просто опасаюсь что %lld будет платформзависимым
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.10.2016, 15:34     Вызов sprintf для типа не соответствующего формату
Еще ссылки по теме:

C++ Аналог sprintf
C++ Sprintf
Считать данные из файла и записать в переменные соответствующего типа C++
Странный sprintf C++
Переговоры о разработке любого проекта для разработки соответствующего программного обеспечения C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Avazart
 Аватар для Avazart
7037 / 5214 / 259
Регистрация: 10.12.2010
Сообщений: 22,897
Записей в блоге: 17
08.10.2016, 15:34     Вызов sprintf для типа не соответствующего формату #13
Цитата Сообщение от vxg Посмотреть сообщение
Avazart, я просто опасаюсь что %lld будет платформзависимым
int64_t скорее всего приводится long long который платформозависим, но начиная с С++11 вроде как long long не меньше 64 бит поэтому проблем не должно быть, но на всякий случай стоит поставить assert для проверки размера типа.
Yandex
Объявления
08.10.2016, 15:34     Вызов sprintf для типа не соответствующего формату
Ответ Создать тему
Опции темы

Текущее время: 03:01. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru