Как удалить это предупреждение: второй параметр 'va_start не последний именованный аргумент?
У меня есть функция (см. ниже), которая выдает следующее предупреждение:
второй параметр 'va_start не последний именованный аргумент
Что это значит и как его удалить?
функция имеет следующий вид:
static int ui_show_warning(GtkWindow *parent, const gchar *fmt, size_t size, ...)
{
GtkWidget *dialog = NULL;
va_list args = NULL;
int count = -1;
char *msg = NULL;
if((msg = malloc(size + 1)) == NULL)
return -12;
va_start(args, fmt);
if((count = snprintf(msg, size, fmt, args)) < 0)
goto outer;
dialog = gtk_message_dialog_new(parent,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_OK,
"%s", msg);
(void) gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
outer: {
if(args != NULL)
va_end(args);
if(msg != NULL)
free(msg);
return count;
}
}
Примечание: предложение по улучшению этого кода очень ценится.
Ответы
Ответ 1
Вам нужно использовать size
вместо fmt
:
va_start(args, size);
Это size
, а не fmt
, это последний параметр с явным именем (в отличие от параметров vararg, у которых нет имен). Вам необходимо передать последний именованный параметр в va_start
, чтобы он мог определить адрес в памяти, с которой начинаются параметры vararg.
Ответ 2
second parameter of ‘va_start’ not last named argument
Что это значит и как его удалить?
Ваша функция имеет именованные параметры parent
, fmt
и size
. C spec говорит, что вы должны всегда передавать последний именованный параметр в va_start
для совместимости со старыми компиляторами. Поэтому вы должны пройти size
, а не fmt
.
(Но с современным компилятором он может работать в любом случае)
Ответ 3
Я думаю, что здесь возникает путаница: большинство людей имеют дело только с prinf-подобными функциями, которые имеют формат и varargs. и они думают, что им нужно передать имя параметра, которое описывает формат. однако va_start не имеет ничего общего с каким-либо форматом printf. это просто функция, которая вычисляет смещение в стеке, где начинаются безымянные параметры.