1

考虑以下代码示例:

#define STRING_LITERAL  "%u, %u"
const char string_const[ ] = "%u, %u";

snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);

然后我的编译器发出警告:格式字符串在此参数之前结束

现在,如果我将指令更改为:

snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3);

然后编译器不会发出警告。

我的问题是:这样的行为是否符合 C99 标准?

4

5 回答 5

1

我的问题是:这样的行为是否符合 C99 标准?

这两个示例都调用了未定义的行为,但没有违反约束或语法规则,因此不需要诊断。

于 2015-04-22T09:52:45.850 回答
1

警告是由编译器生成的,它能够确定您向调用传递了不正确的参数,而第二次没有。

该标准定义传递不正确的参数和/或使用不正确的标志会导致未定义的行为。

标准不需要警告,它只是对程序员的额外帮助。

于 2015-04-22T09:52:56.137 回答
0

你的论点太多,应该是:

#define STRING_LITERAL  "%u, %u"
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2);

或者:

#define STRING_LITERAL  "%u, %u, %u"
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);

没有警告的原因是它是未定义的行为,只有当编译器足够聪明地认为有问题时才会发出警告。如果字符串直接在 snprintf 命令中,编译器似乎足够聪明,如果字符串是间接传递的,它似乎不是。

于 2015-04-22T09:53:20.393 回答
0

在这个例子中

snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);

你直接传递一个字符串文字,而在这个

snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3);

你正在传递一个变量。

我假设您的编译器(无论是什么编译器)出于相关警告的目的而将文字与变量区别对待。

于 2015-04-22T09:59:37.117 回答
0

我在 C99 标准的附件 I(常见警告)中找到了以下声明,阐明了这种情况。

1 在许多情况下,实施可能会产生警告,但本国际标准均未将这些警告指定为部分。以下是一些比较常见的情况。

于 2015-04-24T07:34:43.033 回答