没有参数的格式说明符
Format specifier without argument
考虑以下代码示例:
#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标准?
My question is: does such a behavior comply with C99 standard?
两个示例都调用了未定义的行为,但没有违反约束或语法规则,因此不需要诊断。
警告由编译器生成,它能够确定您向调用传递了不正确的参数,而在第二个调用中没有。
标准定义使用不正确的标志传递不正确的参数 and/or 会导致未定义的行为。
该警告不是标准所要求的,它只是对程序员的额外帮助。
你的参数太多,应该是:
#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 命令中,编译器似乎足够聪明,如果字符串是间接传递的,它似乎不是。
在这个例子中
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);
你直接传递了一个字符串文字,而在这个
snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3);
您正在传递一个变量。
我假设您的编译器(无论是哪个编译器)出于相关警告的目的将文字与变量区别对待。
我在 C99 标准的附录 I(常见警告)中找到了以下声明,阐明了这种情况。
1 An implementation may generate warnings in many situations, none of which are
specified as part of this International Standard. The following are a few of the more common situations.
考虑以下代码示例:
#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标准?
My question is: does such a behavior comply with C99 standard?
两个示例都调用了未定义的行为,但没有违反约束或语法规则,因此不需要诊断。
警告由编译器生成,它能够确定您向调用传递了不正确的参数,而在第二个调用中没有。
标准定义使用不正确的标志传递不正确的参数 and/or 会导致未定义的行为。
该警告不是标准所要求的,它只是对程序员的额外帮助。
你的参数太多,应该是:
#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 命令中,编译器似乎足够聪明,如果字符串是间接传递的,它似乎不是。
在这个例子中
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);
你直接传递了一个字符串文字,而在这个
snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3);
您正在传递一个变量。
我假设您的编译器(无论是哪个编译器)出于相关警告的目的将文字与变量区别对待。
我在 C99 标准的附录 I(常见警告)中找到了以下声明,阐明了这种情况。
1 An implementation may generate warnings in many situations, none of which are specified as part of this International Standard. The following are a few of the more common situations.