我有一个发出以下警告的功能(见下文):
'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;
}
}
答案 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
它意味着什么以及如何删除它?
您的函数已命名参数parent
,fmt
和size
。 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();
}
问题已解决。