Удивительное рядом - 2. vsnprintf
От: Dair Россия  
Дата: 12.05.16 22:27
Оценка: 1 (1)
Присказка:
Сегодня клиент из Поднебесной пишет, что в некотором месте игра на Android 4 работает, а на 6.0.1 — не работает.

Полез разбираться.
Взял два Android-телефона, на одном 4.4.2, на другом — 6.
Баг воспроизводится.

Удивительно — думаю я. В конкретно этом месте к OS какой бы то ни было вообще обращений нет. Один и тот же код одинаково работает на iOS, Android, Win32, Win8/10, OS X.

Поскольку у меня нет настроенного окружения для отладки C++ под Android, отлаживаюсь дебажным выводом.


Сказка:

Есть у нас в игре функция общего назначения, используемая и в хвост и в гриву:
std::string formatString(const char* format, ...)


Берёт строчку-форматтер в формате printf, при помощи vsnprintf подставляет в неё параметры, отдаёт std::string на выходе.

В моём случае в эту функцию отдаётся формат и один строковый параметр. Но в формате нет никакого %s — особенности китайской локализации.
Согласно стандарта, функция должна бы просто вернуть строчку-формат, забыв про аргумент.

Так и происходит на Android4.

В мане пишут:
[q]Concerning the return value of snprintf(), SUSv2 and C99 contradict each other: when snprintf() is called with size=0 then SUSv2 stipulates an unspecified return value less than 1, while C99 allows str to be NULL in this case, and gives the return value (as always) as the number of characters that would have been written in case the output string has been large enough. [/b]

Но на SUSv2 всегда было покласть — это стандарт каких-то толстых юниксов типа Solaris, которые нашей таргет-платформой никогда не были.

А на Android6 (на Android5 не проверял, но, вроде, так же как и на 6) vsnprintf(NULL, 0, ...) возвращает 1, и, впоследствии, записывает туда пустую строку (один только 0).


Как править — понятно. Но сам факт.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.