В настоящее время я конвертирую код одной из наших библиотек Linux в DLL Windows.
Внутри этой библиотеки у меня есть функция, которая принимает последние параметры в printf-way (строка форматирования, затем многоточие). Внутри этой функции я использую vsnprintf для форматирования прилагаемых аргументов. Поскольку я хочу знать, могу ли я втиснуть финальную строку в небольшой буфер или если мне придется выделять памяти для меня, я заинтересован в определении "длины длины" форматированной строки.
Для этого в настоящее время я использую vsnprintf как это (например, код примера):
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
void foo(const char* fmt, ...)
{
int len = 0;
va_list ap;
va_start(ap, fmt);
len = vsnprintf(0, 0, fmt, ap);
printf("len = %d\n", len);
va_end(ap);
}
int main(void)
{
foo("12345%s", "67890");
exit(0);
}
Это использование покрывается Open Base Base Specifications Issue 6:
vsnprintf (char * ограничивать s, size_t n, const char * ограничивать формат, va_list ap)
Функции [...] vsnprintf() [...] должны быть эквивалентны [...] snprintf().
snprintf (char * ограничивать s, size_t n, const char * ограничивать формат,...)
Если значение n равно нулю при вызове snprintf(), ничего не должно быть записано, число байтов, которое было бы написано, было бы достаточно большим, исключая завершающий нуль, и оно может быть нулевой указатель.
Проблема возникла, когда я компилировал этот код в Windows-System (Visual Studio 2010) с помощью /analysis on. Компилятор/анализатор дал мне следующее:
test.c(11): предупреждение C6309: аргумент '1' имеет значение null: это не соответствует спецификации функции 'vsnprintf'
test.c(11): предупреждение C6387: "аргумент 1" может быть "0": это не соответствует спецификации функции "vsnprintf": Линии: 7, 8, 10, 11
Быстрый просмотр записи MSDN для vsnprintf дал мне следующее:
Если буфер или формат NULL, или если количество меньше или равно нулю, эти функции вызывают недопустимый обработчик параметров, как описано в разделе Проверка параметров. Если выполнение разрешено продолжить, эти функции возвращают -1.
Любопытно, что вышеприведенный образец работает, тем не менее, в Windows "как и ожидалось" (т.е. возвращает мне счет символов, которые будут записаны).
Но так как я не хочу, чтобы это полагалось на что-то неуказанное, я хотел бы знать, есть ли лучший, официальный способ добиться того же самого, не надеясь, что это не сломается в какой-то будущей версии.
Спасибо за ваше время!