如何删除此警告:'va_start'的第二个参数不是最后命名的参数?

Jac*_*ack 20 c linux gcc

我有一个发出以下警告的功能(见下文):

'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;
      }
    }
Run Code Online (Sandbox Code Playgroud)

das*_*ght 24

您需要使用size而不是fmt:

va_start(args, size);
Run Code Online (Sandbox Code Playgroud)

size不是fmt具有显式名称的最后一个参数(与没有名称的vararg参数相反).您需要传递最后一个命名参数va_start,以便它在内存中找出vararg参数开始的地址.

  • 我仍然对答案感到困惑。什么是尺寸?我有一个这样的函数: void function(int, const string&amp; fmt, ...);,当我使用 va_start 时,会显示此警告。那我需要做什么呢? (2认同)

use*_*876 6

second parameter of ‘va_start’ not last named argument
Run Code Online (Sandbox Code Playgroud)

它是什么意思以及如何删除它?

你的函数命名参数parentfmtsize。C规范指出,必须始终将最后一个命名的参数传递给va_start,以与较早的编译器兼容。所以你必须通过size,而不是fmt

(但是使用现代编译器,它仍然可以工作)


mis*_*hru 5

我认为这里存在一个混乱:大多数人只处理类似 prinf 的函数,它们具有格式和可变参数。他们认为必须传递描述格式的参数名称。然而 va_start 与任何类似 printf 的格式无关。这只是一个计算未命名参数开始的堆栈偏移量的函数。