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

时间:2012-11-02 04:35:13

标签: 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;
      }
    }

4 个答案:

答案 0 :(得分:23)

您需要使用size代替fmt

va_start(args, size);

它是size,而不是fmt,它是具有显式名称的最后一个参数(与没有名称的vararg参数相对)。您需要将最后一个命名参数传递给va_start,以便它能够计算出内存中vararg参数开始的地址。

答案 1 :(得分:5)

second parameter of ‘va_start’ not last named argument
     

它意味着什么以及如何删除它?

您的函数已命名参数parentfmtsize。 C规范说你必须始终将最后一个命名参数传递给va_start,以便与旧版编译器兼容。因此,您必须通过size,而不是fmt

(但是使用现代编译器,无论如何都可以工作)

答案 2 :(得分:3)

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

答案 3 :(得分:0)

我在Ubuntu20.04上遇到了同样的问题,与最喜欢的答案相反, 开头的代码,

public static boolean isFileDownloaded(String downloadPath, String fileName) {
   File dir = new File(downloadPath);
   File[] dir_contents = dir.listFiles();

   if (dir_contents != null) {
       for (File dir_content : dir_contents) {
            if (dir_content.getName().equals(fileName))
                return true;
       }
   }

   return false;
}

然后,代码如下

public static String getDownloadsPath() {

   String downloadPath = System.getProperty("user.home");
   File file = new File(downloadPath + "/Downloads/");
   return file.getAbsolutePath();
}

问题已解决。