1

我正在尝试学习 C,但我已经遇到了问题。我认为它微不足道,但我需要知道它。我已经写了:

char *seconds_to_string (guint seconds)
{
    long days, hours, minutes;
    char *time = NULL;
    const char *minutefmt;
    const char *hourfmt;
    const char *secondfmt;

    days    = seconds / (60 * 60 * 24);
    hours   = (seconds / (60 * 60));
    minutes = (seconds / 60) - ((days * 24 * 60) + (hours * 60));
    seconds = seconds % 60;

    minutefmt = ngettext ("%ld minute", "%ld minutes", minutes);
    hourfmt = ngettext ("%ld hour", "%ld hours", hours);
    secondfmt = ngettext ("%ld second", "%ld seconds", seconds);

    minutefmt = ngettext ("%ld minute", "%ld minutes", minutes);
    hourfmt = ngettext ("%ld hour", "%ld hours", hours);
    secondfmt = ngettext ("%ld second", "%ld seconds", seconds);

    char *fmt;
    /* Translators: the format is "X hours X minutes X seconds" */
    fmt = g_strdup_printf (_("%s %s %s"), hourfmt, minutefmt, secondfmt);
    time = g_strdup_printf (fmt, hours, minutes, seconds);
    g_free (fmt);

    ---------------------------------------------------------------------

    return time;
}

警告符合:

time = g_strdup_printf (fmt, hours, minutes, seconds);

有人可以帮忙吗?

更新:

编译

scan-build make CFLAGS='-Wformat-nonliteral'
4

2 回答 2

3

这只是一个警告。

g_strdup_printf(), like printf(), 使用第一个参数作为格式说明符,如果是字符串字面量 like "%d Hours:%d Minutes",编译器可以检查后面的参数,看类型是否匹配。(在本例中,如果两个参数的类型为int

但是在您的代码中,格式说明符不是字符串文字,而是您手动生成的字符串,因此编译器无法为您检查类型。

于 2013-09-28T08:01:40.533 回答
0

如果不指定您正在使用的编译器,很难确定,但在我看来,您收到的警告似乎是良性的。看起来您的编译器通常可以printf根据提供的格式字符串对调用进行一些检查:例如,如果您说它printf("%d", arg1, arg2)可能会注意到您的格式字符串需要一个参数,但您的printf调用提供了两个参数。

但是在您的代码中,格式字符串不是文字,而是由其他函数产生的值。编译器不够聪明,无法弄清楚该字符串应该是什么,因此它会向您发出警告,告诉您它不会为您提供您可能期望的安全网。

只要您确定生成警告的调用实际上是正确的,就可以安全地忽略或抑制此警告。

于 2013-09-28T08:03:20.143 回答